2013-10-31 27 views
3

在我的代碼中,我希望在應用程序加載數據時清除TextArea。我還添加了重繪(),但仍未清除。 我是否必須以不同的方式通知它才能強制重畫?如何在ActionListener正在進行時更新擺動UI

button.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent event) { 
      textArea.setText(""); 
      textArea.repaint(); 


      String result = //call a REST API 
      textArea.setText(result); 
     } 
    }); 
+1

您不必調用repaint()明確性,您想要做的就是在另一個線程中調用其餘的api – nachokk

+3

ActionListener的acitionPerformed方法在EDT上執行。 EDT是處理UI更新(重繪)的線程。從EDT調用「重新繪製」將在處理待處理事件後立即安排重新繪製。當你用美國國家航空航天局(REST)的電話召開美國國家航空航天局(EDT)時,重繪不會發生。 – afk5min

回答

1

只是在另一個線程中做耗時的操作。您可以使用SwingWorker,計算完成後會立即通知AWT線程。

public void actionPerformed(ActionEvent event) { 
    textArea.setText(""); 

    SwingWorker<String, Object> worker = new SwingWorker<String, Object>() { 
     @Override 
     protected String doInBackground() throws Exception {     
      return ...; // call a REST API 
     } 
     @Override 
     protected void done() { 
      try { 
       textArea.setText(get()); 
      } catch (Exception e) { 
       //ignore 
      } 
     } 
    };  
    worker.execute(); 
} 

您還可以使用invokeLater,將執行REST調用的事件隊列的一部分。

public void actionPerformed(ActionEvent event) { 
    textArea.setText(""); 

    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      String result = // call a REST API 
      textArea.setText(result); 
     } 
    }); 
} 
+1

除了應該從EDT調用「textArea.setText(result)」。 SwingWorker在這種情況下更適合。 – afk5min

+0

對,編輯爲使用StringWorker – rzymek

+0

實際上,'invokeLater()'在這裏也可以。它也[在EDT中執行代碼](http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingUtilities.html#invokeLater(java.lang.Runnable) – rzymek

0

您在EDT運行您的actionPerformed(ActionEvent event)方法,因爲您無法更新UI。要從代碼更新UI,請嘗試使用SwingWorker,它可以在後臺進程運行時更新UI。

或者您可以嘗試使用Executors作爲後臺進程並更新EDT中的UI。

5

我想你想要做的是在另一個線程中調用其餘的api。你可以用SwingWorker來完成這個任務,它可以在不阻塞gui的情況下在另一個線程中大量運行任務。下面是一個完整實施例I真正喜歡Swing Worker Example

實施例:

class Worker extends SwingWorker<Void, String> { 

    @Override 
    protected Void doInBackground() throws Exception { 
     //here you make heavy task this is running in another thread not in EDT 
     // call REST API here 

     return null; 
    } 

   @Override 
   protected void done() { 
        //this is executed in the EDT 
     //here you update your textArea with the result 
   } 
} 

doInBackground方法結束執行done方法。然後SwingWorker通知任何PropertyChangeListener有關狀態屬性更改爲StateValue.DONE。所以你可以在這裏覆蓋這個方法,或者使用propertyChangeListener實現來做你想做的事情。

+0

+1這是我見過的最好的例子Saludos! – dic19

+0

@ dic19 gracias jaja – nachokk

相關問題