EDT和SwingWorker线程-发布和处理

时间:2018-07-19 09:54:57

标签: java multithreading swingworker edt

EDT和SwingWorker的概念有点令人困惑。我已经遍历了两次方法定义,并编写了一些示例程序。

下面是我目前的情况,

1)我已经使用以下方法从main方法启动了一个GUI窗口,

public static void main(String[] args) {
    // TODO Auto-generated method stub
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            final StartMainWindow StartMainWindow = new StartMainWindow();
            StartMainWindow.initActionsAndComponenets();
        }
    });
}

2)StartMainWindow是一个SWT窗口,主要代码是“ RUN”按钮。单击运行按钮后,需要执行一组特定的数据库操作,这些操作将放置在DBOperations类的doInBackground()方法中。此类扩展了SwingWorker。

DBOperations dbOperate = new DBOperations(currentFileToBeProcessed, currentFileListObject, unstreamOutputs, saveCanonicals, clientId, systemDestin, text, true);
dbOperate.execute();

3)我删除了所有DBOperations代码,并放入了一些示例代码,以使其更易于理解。在DBOperations中,下面是代码,

public class DBOperations extends SwingWorker<Integer, String>{
    @Override
    protected Integer doInBackground() throws Exception {
        Thread.sleep(2000);
        publish("String");
        System.out.println("Entered");
        Thread.sleep(5000);
        publish("String");
        System.out.println("Entered..");
        Thread.sleep(2000);
        publish("String");
        System.out.println("Entered....");
        Thread.sleep(2000);
        publish("String");
        System.out.println("Entered......");
        publish("String");
        publish("String");
        publish("String");
        publish("String");
    }

    @Override
    protected void process(List<String> chunks) {
        // TODO Auto-generated method stub
        System.out.println("Entered text update....");
        for (String string : chunks) {
            System.out.println(string);
        }
    }
}

运行代码时,它会启动一个窗口,并仅显示“ Entered”。

关闭窗口后,它将打印我使用publish发送的所有内容。因此,实际的事件顺序如下,

Entered
Entered..
Entered....
Entered......
**CLOSES WINDOW
String
String
String
String
String
String
String
String

使用发布时,应立即打印到标准输出。为什么会发生这种情况并提供修复建议?

1 个答案:

答案 0 :(得分:0)

我无需使用任何SwingWorker概念即可解决此问题。如MadProgrammer所述,SWT具有自己的线程模型。我最后要做的是以下

1)在我的DBOperations类上实现可运行接口。然后添加一个名为updateTextArea的方法,该方法执行asyncExec(SWT中提供的方法)以将字符串异步附加到文本区域,并输出到stdout。

public class DBOperations implements Runnable{
    @Override
    public void run() {
      try {
        Thread.sleep(2000);
        updateTextArea("String");
        System.out.println("Entered");
        Thread.sleep(5000);
        updateTextArea("String");
        System.out.println("Entered..");
        Thread.sleep(2000);
        updateTextArea("String");
        System.out.println("Entered....");
        Thread.sleep(2000);
        updateTextArea("String");
        System.out.println("Entered......");
        /****DB operations performed here****/
        /****DB operations performed here****/
        /****DB operations performed here****/
        /****DB operations performed here****/
        updateTextArea("String");
        updateTextArea("String");
        updateTextArea("String");
        updateTextArea("String");
      } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
      }
    }

    public void updateTextArea(String updateText) {
        Display.getDefault().asyncExec(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                text.append(updateText + "\n");
                System.out.println(updateText);
            }
        });
    }
}

asyncExec()确保在执行DBOperations时更新了文本区域和stdout,从而解决了问题。