简体   繁体   English

Java的Swing Threading

[英]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.invokeAndWaitSwingUtilities.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM