2010-08-10 67 views
0

我正在製作一個動畫,當我按下按鈕時,相應表格的每一行都從上到下逐一突出顯示。但是,當動畫開始時,表格無法正確重繪,表格的ui以某種方式損壞。這裏是我的代碼如下。在另一個線程的JScrollPane中更新表格

/* 

*要更改此模板,請選擇工具|模板 *並在編輯器中打開模板。 */

/* * TableFrame.java * *創建於2010年8月5日,下午4點07分10秒 */

封裝測試; import javax.swing。 ; import javax.swing.table。; /** * * @作者管理員 */ public class TableFrame extends javax.swing.JFrame { StringThread1 t = null;

public JTable table; public JScrollPane getScrollPane(){ return this.jScrollPane1; } /**創建新表格TableFrame */ public TableFrame(){ initComponents(); table = new JTable(new javax.swing.table.DefaultTableModel(100,2)); this.jScrollPane1.setViewportView(table); (int i = 0; j < 2; j ++){ table.setValueAt(new Integer(i),i,j); } } t = new StringThread1(this); }

/** This method is called from within the constructor to 
* initialize the form. 
* WARNING: Do NOT modify this code. The content of this method is 
* always regenerated by the Form Editor. 
*/ 
@SuppressWarnings("unchecked") 
// <editor-fold defaultstate="collapsed" desc="Generated Code">       
private void initComponents() { 

    jScrollPane1 = new javax.swing.JScrollPane(); 
    jButton1 = new javax.swing.JButton(); 

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

    jScrollPane1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); 

    jButton1.setText("jButton1"); 
    jButton1.addActionListener(new java.awt.event.ActionListener() { 
     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      jButton1ActionPerformed(evt); 
     } 
    }); 

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
    getContentPane().setLayout(layout); 
    layout.setHorizontalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGroup(layout.createSequentialGroup() 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addGroup(layout.createSequentialGroup() 
        .addContainerGap() 
        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)) 
       .addGroup(layout.createSequentialGroup() 
        .addGap(32, 32, 32) 
        .addComponent(jButton1))) 
      .addContainerGap()) 
    ); 
    layout.setVerticalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGroup(layout.createSequentialGroup() 
      .addContainerGap() 
      .addComponent(jButton1) 
      .addGap(18, 18, 18) 
      .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 201, javax.swing.GroupLayout.PREFERRED_SIZE) 
      .addContainerGap(48, Short.MAX_VALUE)) 
    ); 

    pack(); 
}// </editor-fold>       

boolean play = false; 
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {           
    this.t.start(); 
     play = !play; 
}           

class StringThread1 extends Thread 
{ 
    private TableFrame str; 

    StringThread1 (TableFrame s) 
    { 
     str=s; 
    } 

    public void run() { 
     int y = 0; 
     while(true){ 
      try{ 
       System.out.println("y " + String.valueOf(y)); 
       this.sleep(500); 
       this.str.table.setRowSelectionInterval(y, y); 
       int rp = y * this.str.table.getRowHeight(); 
       int halfHeight = this.str.getScrollPane().getHeight()/2 - this.str.table.getRowHeight(); 
       if(rp + this.str.table.getRowHeight() * 2 >= this.str.getScrollPane().getVerticalScrollBar().getValue() + this.str.getScrollPane().getHeight()){ 
        this.str.getScrollPane().getVerticalScrollBar().setValue((y) * this.str.table.getRowHeight()); 
       } 

       else{ 
        this.str.getScrollPane().getVerticalScrollBar().setValue(0); 
       } 


       if(y == 99){ 
        y = 0; 
       }y+= 1; 
      } catch(InterruptedException e){} 
     } 
    } 
} 

/** 
* @param args the command line arguments 
*/ 
public static void main(String args[]) { 
    java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      new TableFrame().setVisible(true); 
     } 
    }); 
} 

// Variables declaration - do not modify      
private javax.swing.JButton jButton1; 
private javax.swing.JScrollPane jScrollPane1; 
// End of variables declaration     

}

回答

1

有一個黃金法則 - 在事件Displatch線程之外的線程不會操作所顯示的圖形用戶界面項目。所以,你需要使用SwingUtilities.invokeLater()做這些調用:

this.str.table.setRowSelectionInterval(y, y); 

this.str.getScrollPane().getVerticalScrollBar().setValue((y) * this.str.table.getRowHeight()); 

this.str.getScrollPane().getVerticalScrollBar().setValue(0); 

你可以用每一個,或包裹他們都在一個電話。

+0

它的工作原理!但是invokeLater做了什麼魔術? – user415726 2010-08-10 07:47:46

+0

您能否接受我的回答(打個勾)? invokeLater將您的作業引發到EventDispatch隊列中,並且EventDispatch線程將挑選作業並處理它們 - 以保持您的GUI正常運行。 – 2010-08-10 08:08:49

+0

對不起,新來stackflow – user415726 2010-08-10 08:38:55

相關問題