Java的Swing Threading
我的理解是,如果我启动另一个线程来执行某些操作,我需要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(); } } );
希望这是朝着正确方向迈出的一步,如果您认为有更好的方法来处理我的情况,请发表评论。
在我看来,你几乎不应该使用invokeAndWait()
。 如果某些事情需要一段时间才会锁定你的UI。
使用SwingWorker
进行此类操作。 在Java SE 6中查看使用SwingWorker提高应用程序性能 。
您应该考虑使用SwingWorker
因为它不会阻止UI线程,而两个SwingUtilities
方法都将在EDT线程上执行,从而阻止UI。
我在EventQueue.invokeLater(...)
保留了简单的Thread
,并且顺利运行…
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(); } });