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"),但是甚至没有打印出来.我在方法调用之前和之后添加了断点并尝试调试,但这也没有帮助.一切似乎都很好,我找不到问题.
编辑
我问:如何只在我希望它显示时才显示对话框?换句话说,脚本是:
立即关闭,我发现你正在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用于后台工作.
代替
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调用将被运行后台线程所需的时间阻塞.