Java的Swing Threading

我的理解是,如果我启动另一个线程来执行某些操作,我需要SwingUtilities.invokeAndWaitSwingUtilities.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(); } });