【发布时间】:2011-02-03 14:19:47
【问题描述】:
我的理解是,如果我启动另一个线程来执行某些操作,我将需要SwingUtilities.invokeAndWait 或SwingUtilities.invokeLater 在我处于所述线程时更新 GUI。如果我错了,请纠正我。
我想要完成的事情相对简单:当用户单击提交时,我想(在执行任何操作之前)禁用提交按钮,执行操作,并在操作结束时重新启用按钮.我执行该操作的方法在返回结果时直接更新 GUI(显示结果)。
此操作基本上是查询服务器并返回一些结果。
到目前为止我所拥有的是:
boolean isRunning = false;
synchronized handleButtonClick() {
if ( isRunning == false ) {
button.setEnabled( false );
isRunning = true;
doAction();
}
}
doAction() {
new Thread() {
try {
performAction(); // Concern A
} catch ( ... ) {
displayStackTrace( ... ); // Concern B
} finally {
SwingUtilities.invokeLater ( /* simple Runnable to enable button */ );
isRunning = false;
}
}
}
对于上述两个问题,我是否必须使用SwingUtilities.invokeAndWait,因为它们都会更新 GUI?所有 GUI 更新都围绕更新 JTextPane。我是否需要在我的线程中检查我是否在 EDT 上,如果是,我可以调用我的代码(无论它是否更新 GUI)而不使用 SwingUtilities.invokeAndWait?
编辑:这是我现在正在做的事情:
handleButtonClick() {
if ( isRunning == true )
return;
disable button;
SwingWorker task = new MyTask();
task.execute();
}
...inside MyTask
doInBackground() {
return performAction();
}
done() {
result = get();
enable button;
isRunning = false;
interpret result (do most of the GUI updates here);
}
虽然performAction() 进行了一些 GUI 更新,但我已将其包装在:
if ( SwingUtil.isEDT() )
doGUIupdate()
else
SwingUtil.invokeLater( new Runnable() {
run() {
doGUIupdate();
}
} );
希望这是朝着正确方向迈出的一步,如果您认为有更好的方法来处理我的情况,请发表评论。
【问题讨论】:
-
使用 SwingWorker。 java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html
-
我的印象是 SwingWorker 应该用于“长”的东西,而 SwingUtilities 用于“快速”的东西?
-
因为 SwingUtilities 在“UI”线程上执行,它必须用于快速实用的东西;否则它可能会阻止用户界面。两者都不会在“另一个线程”中执行。
标签: java swing multithreading