Ron*_*ony 2 java user-interface swing multithreading event-dispatch-thread
我是Swing的新手,目前正在尝试在NetBeans中开发一个简单的GUI应用程序.
我想创建某种GUI日志记录系统,将应用程序正在执行的当前操作写入TextArea.
举个简单的例子,我创建了一个只包含2个对象的JFrame表单:一个"开始"按钮和一个TextArea.
当按下"开始"按钮时,它会调用某种冗长的方法,该方法需要一些时间(比方说,10秒)才能完成运行,并且在此方法运行时,我想将文本追加到TextArea中冗长的方法(当然我希望TextArea能够立即更新).
我的问题是我无法找到正确的方法.无论如何我尝试这样做,当我按下"开始"按钮时,应用程序冻结了10秒钟,没有像我想要的那样更新TextArea.只有在方法完成后,我才会看到TextArea的更新.
这是一个示例代码:
private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {
try {
for (int i = 0; i < 10; i++) {
textArea.setText(i + "\n");
Thread.sleep(1000);
}
} catch (Exception e) {}
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我希望看到的是,一旦我单击按钮,在接下来的10秒内,每隔一秒就会在TextArea上附加一行,如下所示:
1
2
3
4
...
但是我从这段代码得到的真实结果是应用程序冻结了10秒钟,最后TextArea被更新并仅显示数字9.
我已经尝试了许多不同的方法,主要使用SwingUtilities.invokeLater和SwingWorker方法,但它们都不适合我.
任何帮助找到正确的方法,将不胜感激.
1.始终保持UI工作在UI线程上,非UI工作在非UI线程上.
2.在Java GUI应用程序中,main()方法不长,在调度GUI的构造之后Event Dispatcher Thread,main()方法退出......现在它的EDT负责处理GUI.
3.始终保留EDT线程,这是仅用于GUI工作的GUI线程.
例如:
public static void main(String[] args){
EventQueue.invokeLater(new Runnable(){
public void run(){
myframe.setVisible(true);
}
}
}
Run Code Online (Sandbox Code Playgroud)
4.创建一个单独的Non-UI 线程来处理这个长时间的方法.
5.您可以简单地使用Java中专门引入的Thread或使用SwingWorker来同步UI和非UI线程.
就像在其他答案中所说的那样,你会想要使用SwingWorker- 我建议阅读它,因为它是一个非常有用的工具.此实现应该为您提供样本中的内容:
你按钮的动作:
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
new Worker().execute();
}
});
Run Code Online (Sandbox Code Playgroud)
你的摇摆工人:
public class Worker extends SwingWorker<String, String>{
@Override
protected String doInBackground() throws Exception {
//This is what's called in the .execute method
for(int i = 0; i < 10; i++){
//This sends the results to the .process method
publish(String.valueOf(i));
Thread.sleep(1000);
}
return null;
}
protected void process(List<String> item) {
//This updates the UI
textArea.append(item + "\n");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5749 次 |
| 最近记录: |