我正在开发一个Swing应用程序,我需要在后台运行一个无限循环(运行直到:1)我的JDialog的取消按钮被选中或2)它正在搜索的输入数据是当模态对话框显示不确定的进度条时。
我注意到的是,如果JDialog是模态的,那么在JDialog关闭之前,SwingWorker将不会执行其任务(并且在EDT上释放它的死亡句点,我猜......?)。如果JDialog不是模态的,那么SwingWorker的任务将在后台愉快地执行。
我一直在做一些研究,但我没有线程/ EDT专家,并且很难找出原因/解决方案。
对此情况/ threads / EDT / SwingWorker的任何输入或建议的解决方案都将不胜感激。
(问题直接来自:http://www.coderanch.com/t/346275/GUI/java/SwingWorker-Modal-JDialogs)
我尝试了关于JDialog的setVisible调用的解决方案,就像这个用户被发现是解决方案一样,但我仍然不能同时执行两个线程。任何帮助将不胜感激。
相关:
public Dialog(JFrame parentFrame, String equipmentName) {
super(parentFrame, "Progress");
this.hasRequestedCancel = false;
this.equipmentName = equipmentName;
add(createMainPanel());
setIconImage(Toolkit.getDefaultToolkit().getImage(SomeClass.class.getResource(ICON_PATH)));
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setModalityType(ModalityType.DOCUMENT_MODAL);
pack();
setSize(550, 100);
setResizable(false);
setLocationRelativeTo(parentFrame);
setVisible(true);
}
和
SwingWorker<File, Void> worker = createSwingWorker(params, ...);
worker.execute();
并且
private SwingWorker<File, Void> createSwingWorker(final File someFile, final SomeClass asdf, final String param3) throws IOException {
SwingWorker<File, Void> swingWorker = new SwingWorker<File, Void>() {
@Override
protected File doInBackground() throws IOException {
Dialog progressBar = new Dialog(SomeClass.this, SomeClass.this.equipManufacturerDevice);
try {
while(!someFile.exists() && !progressBar.hasRequestedCancel()) {
Thread.sleep(SomeClass.SLEEP_DURATION);
System.out.println("yo");
}
} catch (InterruptedException e) {
}
...
}
@Override
protected void done() {
...
}
};
return swingWorker;
}
答案 0 :(得分:1)
问题是你在setVisible(true)
的构造函数中调用了Dialog
,这是一种沮丧的做法(你只是找到了一个原因,为什么)。
分开对话框的创建和打开,你就不再有这个问题了。以下示例代码演示了如何实现此目的:
final Dialog d=new Dialog((Window)null);
d.setSize(300, 300);
d.setModal(true);
new SwingWorker<Object,Object>() {
@Override
protected Object doInBackground() throws Exception {
System.out.println("long running stuff");
TimeUnit.SECONDS.sleep(10);
System.out.println("end of long running stuff");
return null;
}
@Override
protected void done() {
d.dispose();
}
}.execute();
System.out.println("before setVisible(true)");
d.setVisible(true);// will block
System.out.println("after setVisible(true)");
答案 1 :(得分:0)
如果您将数据输入逻辑从主框架移动并使其在单独的专用后台线程上运行,其唯一的工作是侦听连接并处理它们,该怎么办?这将使您的父JFrame处理UI交互,从而在您的一个JDialog具有焦点时,您可以自由地冻结它。