背景SwingWorker线程不执行特定的代码段

Nic*_*lli 1 java debugging swing multithreading swingworker

我找不到更好的方式在问题的标题中表达问题,但希望你能理解......

我有以下代码......

[...]
final JDialog waitingDialog = optionPane.createDialog(optionPane, "Processing in backgroung");

waitingDialog.setLocationRelativeTo(homeFrame);
waitingDialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);


SwingWorker<Void, Void> backgroundThread = new SwingWorker<Void, Void>() {

    @Override
    protected Void doInBackground() throws Exception {
        // Background processing is done here
        System.out.println("[DEBUG] -- Background processing has started");
        MyCustomClass.initParameters();
        System.out.println("DEBUG] -- initParameters() has finished. Starting main processing now...");
        waitingDialog.setVisible(true);
        MyCustomClass.run();
        return null;
    }

    // This is called when background thread above has completed
    @Override
    protected void done() {
        waitingDialog.dispose();
    };
};
backgroundThread.execute();

[and does other things after this...]
Run Code Online (Sandbox Code Playgroud)

......执行得很好,直到它击中MyCustomClass.run().当它应该启动这种方法时,它根本就不这样做.应用程序不会暂停,停止或崩溃...它只是在后台处理完成后继续等待继续,这不会因某种未知原因而发生.

MyCustomClass.run()是一种static方法MyCustomClass.我怀疑问题可能是它的名字 - 运行 - 所以我把它改成了一些随机的东西,比如"doIt()",但问题仍然存在.该方法的第一行很简单System.out.println("I got here"),但是甚至没有打印出来.我在方法调用之前和之后添加了断点并尝试调试,但这也没有帮助.一切似乎都很好,我找不到问题.


编辑
我问:如何只在我希望它显示时才显示对话框?换句话说,脚本是:

  1. 启动SwingWorker时显示"等待"对话框
  2. 当initParameter()发出需要用户输入的选项对话框时(按一个按钮),隐藏/停止/禁用/配置对话框;
  3. 处理恢复后再次显示等待对话框
  4. 由于后台处理已完成,因此处理对话框

Hov*_*els 5

立即关闭,我发现你正在SwingWorker的doInBackground中进行Swing调用,这完全违背了使用SwingWorker或后台线程的目的.此外,您正在进行的呼叫,一个显示模式对话框的呼叫:

waitingDialog.setVisible(true); // **** here ****
MyCustomClass.run();   // **** not sure what this does or if this makes Swing calls or not.
Run Code Online (Sandbox Code Playgroud)

将暂停其下方的所有代码流,直到对话框不再可见,因为这是模态对话框的功能.这就是阻止你的SwingWorker的原因.您必须尝试分离代码,以便仅在Swing事件线程上进行Swing调用,并仅将worker用于后台工作.

代替

  • 创建您的SwingWorker
  • 执行你的SwingWorker
  • 然后调用setVisible(true)你的模态对话框

在伪代码中:

create modal dialog
create SwingWorker
Attach any PropertyChangeListeners to the SwingWorker (if needed)
Execute the SwingWorker
Display the modal dialog
Run Code Online (Sandbox Code Playgroud)

所以,第一个快换我会做你的代码上面会删除waitingDialog.setVisible(true);从你的SwingWorker的doInBackground()方法,然后调用waitingDialog.setVisible(true);方法执行的SwingWorker,即backgroundThread.execute后(); 特别是.我知道将其置于可见之前调用dispose似乎是违反直觉的,但相信我,它会以这种方式更好地工作,因为dispose调用将被运行后台线程所需的时间阻塞.