2015-04-29 22 views
0

我試圖在按下按鈕時啓用/禁用標籤,並且希望在事件期間執行此操作,而不是在此之後執行操作。正如你可以看到下面,我嘗試啓用/禁用兩個標籤:lblKeyboard和lblGamepad。在ActionEvent期間更改標籤

它們最終會在「RemoteControl.run();」之後運行被執行,但我希望它在此之前發生。任何方式我可以做到這一點?

謝謝!在事件監聽

JButton btnGamepad = new JButton("Gamepad"); 
     btnGamepad.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 

        if(cont_state == 0){ 
         if(RemoteControl.findGamePad() == true){ 
          cont_state = 1; 
          game_status = "on"; 
         } 
         else{ 
          game_status = "off"; 
          key_status = "on"; 
          JOptionPane.showMessageDialog(null, "Controller not found!"); 
          cont_state = 0; 
         } 
        } 

        if(cont_state == 1){  

         System.out.println("CONNECTED GAMEPAD!"); 
         lblKeyboard.disable(); 
         lblGamepad.enable(); 
         frame.repaint(); 
         RemoteControl.run(); 

         cont_state = 0; 
        } 

      } 
     }); 

回答

1

ActionEvents在EDT上運行,它也負責繪畫。一旦您更改了標籤狀態,Swing就會發出請求以修復Label。問題是這個請求被髮布在一個隊列中,一旦EDT被釋放後就會被執行,正如你所看到的,EDT正在忙着運行你的代碼,所以沒有爲你重新繪製!根據代碼的性質,你應該考慮使用SwingWorker或簡單地移動RemoteControl.run()到另一個線程在

new Thread(new Runnable() { 
    @override 
    public void run() { 
      RemoteControl.run(); 
    } 
}).start(); 
+0

感謝您的幫助! SwingWorker現在對我來說非常棒!該計劃的狀態甚至比我預期的更好! – Serpace

1

代碼執行的事件指派線程(EDT)和GUI,直到所有的代碼已經執行完畢,無法重繪自己。有關EDT的更多信息,請閱讀Concurrency上的Swing教程部分。

嘗試將您的RemoteControl.run()代碼包裝在SwingUtilities.invokeLater(...).中這會將代碼放在EDT的末尾,這可能會給Swing更改以重新繪製兩個標籤的狀態。

SwingUtilities.invokeLater(new Runnable() 
{ 
    public void run() 
    { 
     RemoteControl.run() 
    } 
}); 

這假定您的代碼更新了GUI。如果沒有,那麼只需使用一個單獨的線程。