[英]Java's Swing Threading
My understanding is that if I start up another thread to perform some actions, I would need to SwingUtilities.invokeAndWait
or SwingUtilities.invokeLater
to update the GUI while I'm in said thread. 我的理解是,如果我启动另一个线程来执行某些操作,我需要
SwingUtilities.invokeAndWait
或SwingUtilities.invokeLater
来更新GUI,而我在所述线程中。 Please correct me if I'm wrong. 如果我错了,请纠正我。
What I'm trying to accomplish is relatively straightforward: when the user clicks submit, I want to (before performing any actions) disable the submit button, perform the action, and at the end of the action re-enable the button. 我想要完成的是相对简单的:当用户点击提交时,我想(在执行任何操作之前)禁用提交按钮,执行操作,并在操作结束时重新启用按钮。 My method to perform the action updates the GUI directly (displays results) when it gets the results back.
我的执行操作的方法在返回结果时直接更新GUI(显示结果)。
This action basically queries a server and gets some results back. 此操作基本上查询服务器并返回一些结果。
What I have so far is: 到目前为止我所拥有的是:
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;
}
}
}
For both of my concerns above, do I would have to use SwingUtilities.invokeAndWait
since they both will update the GUI? 对于我上面的两个问题,我是否必须使用
SwingUtilities.invokeAndWait
因为它们都会更新GUI? All GUI updates revolve around updating JTextPane
. 所有GUI更新都围绕更新
JTextPane
。 Do I need to in my thread check if I'm on EDT and if so I can call my code (regardless of whether it updates the GUI or not) and NOT use SwingUtilities.invokeAndWait
? 我是否需要在我的线程中检查我是否在EDT上,如果是,我可以调用我的代码(无论是否更新GUI)而不使用
SwingUtilities.invokeAndWait
?
EDIT: Here is what I am doing now: 编辑:这是我现在正在做的事情:
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);
}
While performAction()
does some GUI updates, I have wrapped those in: 虽然
performAction()
执行了一些GUI更新,但我将它们包含在:
if ( SwingUtil.isEDT() )
doGUIupdate()
else
SwingUtil.invokeLater( new Runnable() {
run() {
doGUIupdate();
}
} );
Hopefully this is a step in the right direction, please comment if you believe there are better ways to handle my situation. 希望这是朝着正确方向迈出的一步,如果您认为有更好的方法来处理我的情况,请发表评论。
In my opinion you should almost never use invokeAndWait()
. 在我看来,你几乎不应该使用
invokeAndWait()
。 If something is going to take awhile that will lock your UI. 如果某些事情需要一段时间才会锁定你的UI。
Use a SwingWorker
for this kind of thing. 使用
SwingWorker
进行此类操作。 Take a look at Improve Application Performance With SwingWorker in Java SE 6 . 在Java SE 6中查看使用SwingWorker提高应用程序性能 。
您应该考虑使用SwingWorker
因为它不会阻止UI线程,而SwingUtilities
方法都将在EDT线程上执行,从而阻止UI。
I keep the simple Thread
inside EventQueue.invokeLater(...)
and that worked smoothly... 我将简单的
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();
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.