Java的Swing Threading

nev*_*219 13 java swing multithreading

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

对于我上面的两个问题,我是否必须使用,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);
}
Run Code Online (Sandbox Code Playgroud)

虽然performAction()有一些GUI更新,但我已将它们包含在:

if ( SwingUtil.isEDT() )
  doGUIupdate()
else
  SwingUtil.invokeLater( new Runnable() {
    run() {
      doGUIupdate();
    }
  } );
Run Code Online (Sandbox Code Playgroud)

希望这是朝着正确方向迈出的一步,如果您认为有更好的方法来处理我的情况,请发表评论.

cle*_*tus 18

在我看来,你几乎不应该使用invokeAndWait().如果某些事情需要一段时间才能锁定你的UI.

使用SwingWorker了这种事情.在Java SE 6中查看使用SwingWorker提高应用程序性能.


Jus*_*ier 5

您应该考虑使用,SwingWorker因为它不会阻止UI线程,而两个SwingUtilities方法都将在EDT线程上执行,从而阻止UI.