Java 后台SwingWorker线程未执行特定代码段
我找不到更好的方式来表达问题的标题,但希望你能理解 我有以下代码Java 后台SwingWorker线程未执行特定代码段,java,multithreading,swing,debugging,swingworker,Java,Multithreading,Swing,Debugging,Swingworker,我找不到更好的方式来表达问题的标题,但希望你能理解 我有以下代码 [...] final JDialog waitingDialog = optionPane.createDialog(optionPane, "Processing in backgroung"); waitingDialog.setLocationRelativeTo(homeFrame); waitingDialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_O
[...]
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...]
[…]
final JDialog waitingDialog=optionPane.createDialog(optionPane,“后台处理”);
waitingDialog.setLocationRelativeTo(homeFrame);
waitingDialog.setDefaultCloseOperation(WindowConstants.DO\u NOTHING\u ON\u CLOSE);
SwingWorker backgroundThread=新SwingWorker(){
@凌驾
受保护的Void doInBackground()引发异常{
//后台处理在这里完成
System.out.println(“[DEBUG]--后台处理已启动”);
MyCustomClass.initParameters();
System.out.println(“调试”---initParameters()已完成。现在开始主处理…”);
waitingDialog.setVisible(true);
MyCustomClass.run();
返回null;
}
//当上面的后台线程完成时调用
@凌驾
受保护的void done(){
waitingDialog.dispose();
};
};
backgroundThread.execute();
[在此之后做其他事情…]
。。。在点击MyCustomClass.run()
之前,它会一直正常执行。当它应该启动这样的方法时,它根本没有这样做。应用程序不会暂停、停止或崩溃。。。它只是在后台处理完成后继续等待,这是由于未知的原因而没有发生的
MyCustomClass.run()
是MyCustomClass
上的一个static
方法。我怀疑问题可能出在它的名字-run上-所以我把它改成了一些随机的东西,比如“doIt()”,但问题仍然存在。
该方法的第一行是一个简单的System.out.println(“我在这里得到了”)
,但即使是它也不会被打印出来。
我在方法调用之前和之后添加了断点,并尝试了调试,但也没有帮助。一切似乎都很好,我找不出问题所在
编辑
我问:如何使对话框仅在我希望它显示时才显示?换句话说,脚本是:
我马上就看到你在SwingWorker的后台进行Swing调用,这完全违背了使用SwingWorker或后台线程的目的。此外,您正在拨打的电话显示一个模式对话框:
waitingDialog.setVisible(true); // **** here ****
MyCustomClass.run(); // **** not sure what this does or if this makes Swing calls or not.
将暂停它下面的所有代码流,直到对话框不再可见,因为模态对话框就是这样工作的。这就是阻碍你的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
因此,我在上面的代码中所做的第一个快速更改是删除
waitingDialog.setVisible(true)
从SwingWorkerdoInBackground()
方法,然后调用waitingDialog.setVisible(true)代码>方法在执行SwingWorker之后,即在backgroundThread.execute()之后;特别地。我知道在显示之前调用dispose似乎是违反直觉的,但相信我,这样做会更好,因为dispose调用会被运行后台线程所需的时间阻塞。我立即看到您正在SwingWorker的后台进行Swing调用,完全违背使用SwingWorker或后台线程的目的的东西。此外,您正在拨打的电话显示一个模式对话框:
waitingDialog.setVisible(true); // **** here ****
MyCustomClass.run(); // **** not sure what this does or if this makes Swing calls or not.
将暂停它下面的所有代码流,直到对话框不再可见,因为模态对话框就是这样工作的。这就是阻碍你的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
因此,我在上面的代码中所做的第一个快速更改是删除waitingDialog.setVisible(true)
从SwingWorkerdoInBackground()
方法,然后调用waitingDialog.setVisible(true)代码>方法在执行SwingWorker之后,即在backgroundThread.execute()之后;特别地。我知道在显示它之前调用dispose似乎是违反直觉的,但是相信我,这样做会更好,因为dispose调用会被运行后台线程所需的时间阻止。首先,我接受了@Hovercraft Full Of Eels answer,因为它确实帮助了我。正如我在评论中所说的“简单地将SwingWorker中的setVisible(true)替换为定义后的setVisible(true),使程序按预期流动”,这要归功于他的解释
然而,我还需要一点(这在原始问题的“编辑”部分被描述为一个脚本)。我通过以下代码实现了期望的行为
final JOptionPane optionPane = new JOptionPane("<html>Please wait...<br>Initializing parameters</html>", JOptionPane.INFORMATION_MESSAGE, JOptionPane.DEFAULT_OPTION,
new ImageIcon(Home.class.getResource("/path/to/a/gif/loading.gif")), new Object[]{}, null);
final JDialog waitingDialog = optionPane.createDialog(optionPane, "MyApp");
waitingDialog.setLocationRelativeTo(homeFrame);
waitingDialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
SwingWorker<Void, Void> backgroundThread1 = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
System.out.println("[DEBUG] -- Background processing of initParameters() has started");
MyCustomClass.initParameters();
System.out.println("[DEBUG] -- initParameters() has finished. Moving on...");
return null;
}
@Override
protected void done() {
waitingDialog.setVisible(false);
optionPane.setMessage("<html>Please wait... <br>Now working on your thing.</html>");
};
};
backgroundThread1.execute();
waitingDialog.setVisible(true);
SwingWorker<Void, Void> backgroundThread2 = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
System.out.println("[DEBUG] -- Start now the main processing in background");
MyCustomClass.run();
return null;
}
@Override
protected void done() {
waitingDialog.dispose();
};
};
backgroundThread2.execute();
waitingDialog.setVisible(true);
final JOptionPane optionPane=new JOptionPane(“请稍候…
初始化参数”),JOptionPane.INFORMATION\u消息,JOptionPane.DEFAULT\u选项,
新的图像图标(Home.class.getResource(“/path/t