我的理解是,如果我启动另一个线程来执行某些操作,我需要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();
}
} );
希望这是朝着正确方向迈出的一步,如果您认为有更好的方法来处理我的情况,请发表评论。
答案 0 :(得分:18)
在我看来,你几乎不应该使用invokeAndWait()
。如果某些事情需要一段时间才会锁定你的UI。
使用SwingWorker
进行此类操作。看看Improve Application Performance With SwingWorker in Java SE 6。
答案 1 :(得分:5)
您应该考虑使用SwingWorker
,因为它不会阻止UI线程,而两个SwingUtilities
方法都将在EDT线程上执行,从而阻止了UI。
答案 2 :(得分:0)
我将简单的Thread
保留在EventQueue.invokeLater(...)
内并且顺利运作......
java.awt.EventQueue.invokeLater(new Runnable() {
public void run(){
new Thread(new Runnable(){
public void run(){
try{
EdgeProgress progress = EdgeProgress.getEdgeProgress();
System.out.println("now in traceProgressMonitor...");
while(true){
// here the swing update
if(monitor.getState() == ProgressMonitor.STATE_BUSY){
System.out.println(monitor.getPercentDone()/2);
progress.setProgress(monitor.getPercentDone()/2);
}else{
break;
}
Thread.sleep(5);
}
}catch(InterruptedException ie){}
}
}).start();
}
});