Java';s摆动螺纹

Java';s摆动螺纹,java,swing,multithreading,Java,Swing,Multithreading,我的理解是,如果我启动另一个线程来执行某些操作,我需要SwingUtilities.invokeAndWait或SwingUtilities.invokeLater,以在我处于所述线程时更新GUI。如果我错了,请纠正我 我试图实现的是相对简单的:当用户单击submit时,我想(在执行任何操作之前)禁用submit按钮,执行该操作,并在操作结束时重新启用该按钮。我执行操作的方法在返回结果时直接更新GUI(显示结果) 此操作基本上查询服务器并返回一些结果 到目前为止,我得到的是: boolean i

我的理解是,如果我启动另一个线程来执行某些操作,我需要
SwingUtilities.invokeAndWait
SwingUtilities.invokeLater
,以在我处于所述线程时更新GUI。如果我错了,请纠正我

我试图实现的是相对简单的:当用户单击submit时,我想(在执行任何操作之前)禁用submit按钮,执行该操作,并在操作结束时重新启用该按钮。我执行操作的方法在返回结果时直接更新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();
    }
  } );

希望这是一个正确的步骤,如果你相信有更好的方法来处理我的情况,请评论。

< P>你应该考虑使用<代码> SaveWorks,因为它不会阻止UI线程,而两个<代码> SWIVITUTIOS< /Cord>方法将在EDT线程上执行,因此会阻塞UI。

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


使用
SwingWorker
进行此类操作。看看。

我把简单的
线程
放在
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();

    }
});

使用SwingWorker。我的印象是SwingWorker应该用于“长”的东西,而SwingUtilities应该用于“快”的东西?因为SwingUtilities在“UI”线程上执行,所以必须用于快的东西才能实用;否则它可能会阻塞用户界面。这两个都不会在“另一个线程”中执行。伟大的链接,已经完成了一半,它已经向我透露了很多!invokeAndWait()不会阻止UI—它会阻止帮助线程,直到UI有机会运行传入的Runnable。invokeAndWait()实际上会检查以确保它不是从EDT调用的(这会导致锁)。当然,我应该说,使用CuoKeDand WAITE()通常意味着程序员不能正确地使用事件驱动(观察者)编程…使用<代码>调用和等待> /代码>通常会导致死锁。死锁,请考虑更新它!红色和白色表示无效链接。注意:我是通过在旧链接中找到的Oracle页面中粘贴其名称找到这篇文章的……SwingWorker在EDT上执行其done()方法。这与启动自己的非EDT线程相同,该线程调用SwingWorker.invokeLater()在完成后更新UI。“SwingWorker”的使用比自己滚动要方便一点。@Scott你是说SwingGutilities吗?噢!这应该是SwingUtilities.invokeLater()。谢谢你的帮助。不过我同意现在更喜欢SwingWorker。