2014-12-20 37 views
0

我想從以下最小工作示例中單擊它後在一個小的時間間隔內更改其單選按鈕的文本兩次。即當我點擊按鈕時,我想立即將它的文本改變爲「1」,並且在3秒後將其文本再次改變爲「2」。如何強制java swing gui更新此片段

public class Example extends javax.swing.JFrame { 
    public Example() { 
     jRadioButton1 = new javax.swing.JRadioButton(); 
     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

     jRadioButton1.addItemListener(new java.awt.event.ItemListener() { 
      public void itemStateChanged(java.awt.event.ItemEvent evt) { 
       jRadioButton1ItemStateChanged(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().addGap(137, 137, 137) 
      .addComponent(jRadioButton1).addContainerGap(242, Short.MAX_VALUE)) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup().addGap(126, 126, 126) 
      .addComponent(jRadioButton1).addContainerGap(153, Short.MAX_VALUE)) 
     ); 
     pack(); 
    } 

    private void jRadioButton1ItemStateChanged(java.awt.event.ItemEvent evt) { 
     jRadioButton1.setText("1"); 
     //repaint(); 
     try { Thread.sleep(3000); } 
     catch (InterruptedException e) {} 
     jRadioButton1.setText("2"); 
    } 

    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new Example().setVisible(true); 
      } 
     }); 
    } 

    private javax.swing.JRadioButton jRadioButton1; 
} 

以上顯然不起作用。我知道我應該使用repaint()或SwingUtilities.invokeLater()或者可能以某種方式創建一個新線程,但是我還沒有用它們的任何組合來實現所需的結果。

我該怎麼辦?

在此先感謝。

+6

使用擺動[定時器](http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html)。 'Thread.sleep()'阻塞事件分派線程。 – kiheru

+0

聘請Odesk或自由職業的一些高效人員,他們知道他們會爲你做:) – subash

+0

我想你應該讀這個,也是:http://www.java-samples.com/showtutorial.php?tutorialid=291 – specializt

回答

1

沉睡在事件調度線程中阻止它,並防止發生繪圖發生,因爲你已經發現了。這也使得剩下的UI在當時沒有反應,所以它在你永遠不應該做的事情列表中。

在擺動應用程序中運行延遲或重複動作的標準方式是使用擺動Timer。它在事件派發線程中正確運行動作,因此您也不需要特別注意線程安全。使用Timer您的按鈕動作就變成了:

private void jRadioButton1ItemStateChanged(java.awt.event.ItemEvent evt) { 
    jRadioButton1.setText("1"); 
    Timer timer = new Timer(3000, new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      jRadioButton1.setText("2"); 
     } 
    }); 
    timer.setRepeats(false); 
    timer.start(); 
} 
1

首先,然後改變這

private javax.swing.JRadioButton jRadioButton1; 

public javax.swing.JRadioButton jRadioButton1; 

。你可以寫這個類

public class Updater extends Thread { 

    private Example e ; 

    public Updater(Example e) { 
     this.e = e; 
    } 

    public void run(){ 

     try { 
      Thread.sleep(3000); 
      e.jRadioButton1.setText("2"); 
     } catch (InterruptedException ex){   
     } 

    } 

} 

現在在這裏用這種方法。

private void jRadioButton1ItemStateChanged(java.awt.event.ItemEvent evt) { 
     jRadioButton1.setText("1"); 

     new Updater(this).start(); 
} 
+0

不,不。 Swing是[不是線程安全的](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html)。訪問swing組件(在這種情況下調用'setText()')不應該在事件派發線程之外完成。 – kiheru

+0

你永遠不需要調用Thread.sleep() – Michal