2010-08-10 3 views
0

나는 버튼을 누르면 해당 테이블의 각 행이 위에서 아래로 하나씩 강조 표시되는 애니메이션 작업을하고 있습니다. 그러나 애니메이션이 시작되면 테이블을 올바르게 다시 칠할 수 없으며 테이블의 UI가 손상되었습니다. 여기 내 코드는 다음과 같습니다.다른 스레드의 JScrollPane에서 테이블 업데이트

/* 

*이 템플릿을 변경하려면 도구 | 템플릿 *을 선택하고 편집기에서 템플릿을 엽니 다. */

/* * TableFrame.java 2010년 8월 5일에 만든 * *, 下午 4시 7분 10초 */

패키지 테스트; import javax.swing. ; import javax.swing.table.; /** * * @author 관리자 */ public class TableFrame은 javax.swing.JFrame을 확장합니다. { StringThread1 t = null;

공개 JTable 테이블; public JScrollPane getScrollPane() { 이 this.jScrollPane1을 반환합니다. } /** 새 양식을 만듭니다. TableFrame */ public TableFrame() { initComponents(); table = 새로운 JTable (새로운 javax.swing.table.DefaultTableModel (100, 2)); this.jScrollPane1.setViewportView (table); (int i = 0; i <100; i ++)에 대한 (int j = 0; j< 2; 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 스레드 외부 스레드에 표시되는 GUI 항목을 조작하지 않습니다.

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

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

당신은 각각 포장 할 수
this.str.getScrollPane().getVerticalScrollBar().setValue(0); 

, 또는에서 그들 모두를 포장 : 그래서, 당신은 이러한 호출을 할 SwingUtilities.invokeLater()를 사용합니다 단일 통화.

+0

작동합니다! 그러나 마술은 나중에 무엇을 불러 일으켰습니까? – user415726

+0

내 대답을 수락 할 수 있겠습니까? invokeLater는 작업을 EventDispatch 대기열에 던지고 EventDispatch 스레드가 작업을 선택하여 처리하여 GUI를 계속 작동시킵니다. –

+0

죄송합니다, stackflow의 최신 – user415726

관련 문제