0

EDT 和 SwingWorker 的概念有点令人困惑。我现在已经检查了几次方法定义并编写了一些示例程序。

以下是我目前的情况,

1)我使用以下方法从主要方法启动了一个 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 窗口,主要代码是一个“运行”按钮。单击运行按钮时,需要执行一组特定的 DB 操作,这些操作位于 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”。

关闭窗口后,它会打印我使用发布发送的任何内容。所以实际的事件顺序如下,

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

在使用发布时,它应该立即打印到标准输出。任何解释为什么会发生这种情况以及修复建议?

4

1 回答 1

0

我没有使用任何 SwingWorker 概念就解决了这个问题。正如 MadProgrammer 所说,SWT 有自己的线程模型。我最终做的是以下,

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

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 时更新文本区域和标准输出,这解决了问题。

于 2018-07-27T21:40:06.107 回答