[英]How to update swing UI while ActionListener is in progress
In my code below I want the TextArea to be cleared while the application is loading data. 在我的下面的代码中,我希望在应用程序加载数据时清除TextArea。 I also added a repaint() but still it's not cleared. 我还添加了一个重绘()但仍然没有清除。 Do I have to notify it differently to force a repaint? 我是否必须以不同方式通知它以强制重画?
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
textArea.setText("");
textArea.repaint();
String result = //call a REST API
textArea.setText(result);
}
});
What I think you want to do is calling the rest api in another Thread. 我认为你想做的是在另一个线程中调用其余的api。 You can do it with a SwingWorker
that is designed to run heavily task in another thread without blocking the gui. 您可以使用SwingWorker
来实现它,该SwingWorker
旨在在不阻止gui的情况下在另一个线程中运行大量任务。 Here is a complete example i really like Swing Worker Example 这是一个完整的例子,我非常喜欢Swing Worker Example
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
}
}
After the doInBackground
method is finished the done
method is executed. doInBackground
方法完成后,执行done
方法。 Then SwingWorker
notifies any PropertyChangeListeners about the state property change to StateValue.DONE
. 然后, SwingWorker
StateValue.DONE
任何PropertyChangeListeners状态属性更改通知给StateValue.DONE
。 So you can override this method here or use a propertyChangeListener implementation to do what you want. 因此,您可以在此处覆盖此方法,或使用propertyChangeListener实现来执行您想要的操作。
Just do the time-consuming operation in another thread. 只是在另一个线程中执行耗时的操作。 You can use SwingWorker
, which will notify AWT thread as soon as the computation completes. 您可以使用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();
}
You can also use invokeLater
, which will execute the REST call as a part of the event queue. 您还可以使用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);
}
});
}
You run your actionPerformed(ActionEvent event)
method in EDT because of that you can't update UI. 您在EDT中运行actionPerformed(ActionEvent event)
方法,因为您无法更新UI。 For updating UI from your code try to use SwingWorker , it can update UI while background process running. 要从代码更新UI,请尝试使用SwingWorker ,它可以在后台进程运行时更新UI。
Or you can try to use Executors for background process and updating UI from EDT. 或者您可以尝试使用Executors进行后台处理并从EDT更新UI。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.