SwingWorker,未调用done()方法 [英] SwingWorker, done() method not called
问题描述
这只是SwingWorker的一个实现:
This is, simply an implementation of SwingWorker:
class GuiWorker extends SwingWorker<Integer, Integer> {
private JFrame frame = new JFrame();
private JDialog dialog = new JDialog(frame, "Loadin data", true);
private JProgressBar progressBar = new JProgressBar();
private Statistics st = new Statistics();
public GuiWorker(GraphEditor editor, Statistics st) {
this.st = st;
Window mainWindow = SwingUtilities.windowForComponent(editor
.getGraphComponent().getParent());
dialog.setSize(400, 200);
int x = mainWindow.getX() + (mainWindow.getWidth() - dialog.getWidth())
/ 2;
int y = mainWindow.getY()
+ (mainWindow.getHeight() - dialog.getHeight()) / 2;
progressBar.setString("Have fun to wait some time...");
progressBar.setStringPainted(true);
progressBar.setIndeterminate(true);
dialog.add(progressBar);
dialog.setModal(true);
dialog.setLocation(x, y);
dialog.setVisible(true);
}
@Override
protected Integer doInBackground() throws Exception {
st.loadInitialData();
return 0;
}
@Override
protected void done() {
dialog.setVisible(false);
JLabel label = new JLabel("Task Complete");
dialog.getContentPane().remove(progressBar);
dialog.getContentPane().add(label);
dialog.getContentPane().validate();
dialog.setVisible(false);
}
}
diaglog <的问题/ code>永远不会隐藏,直到我强行关闭它(任务完成后必须隐藏)。
我注意到 loadInitialData()
方法是一种从我的 DB
收集一些统计信息的方法几秒钟。
The problem that diaglog
never hides till I forcely close it (it must be hidden when task finished).
I note that loadInitialData()
method is a method of collecting some stats info from my DB
that takes some few seconds.
UPDATE :我确定 done()
方法是我关闭对话框时调用
。
UPDATE: I am sure that done()
method is called just when I close the dialog
.
更新:
其中我正在使用GuiWorker:
UPDATE: Where I am using GuiWorker is here:
mainTabs.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
switch (mainTabs.getSelectedIndex()) {
case 0:
case 1:
case 2: // stats tab
GuiWorker gw = new GuiWorker(editor,st);
gw.execute();
break;
default:
break;
}
}
});
推荐答案
所有挥杆事件都在事件派遣线程。因此,您添加到 mainTabs
的 ChangeListener
在事件调度线程中运行。
All swing events are run inside the Event Dispatch Thread. So the ChangeListener
that you have added to the mainTabs
runs in the Event Dispatch Thread.
在事件监听器中,您实例化 GuiWorker
并在该构造函数中通过调用 dialog.setVisible打开对话框(true );
。
In the event listener you instantiate the GuiWorker
and in that constructor you open the dialog by calling dialog.setVisible(true);
.
你的JDialog实例是 modal
并且调用 setVislbe(true)
将阻止调用线程,在您的情况下是事件调度线程。因此,在对话框关闭之前,不会调用 gw.execute();
。这就是为什么在关闭对话框之前不会调用 done
方法的原因。
Your JDialog instance is modal
and calling setVislbe(true)
on a modal dialog will block the calling thread, in your case the Event Dispatch Thread. So until the dialog is closed, the gw.execute();
is not called. That is why your done
method is not called until you close the dialog.
为了使代码正常工作,你可以尝试不在构造函数中调用 setVisible(true)
,但提供 GuiWorker
中的方法来设置对话框的可见性。然后调用 gw.execute();
调用 gw.setVisible(true)
。
For your code to work, you can try not calling setVisible(true)
in the constructor but provide a method from the GuiWorker
to set the dialog's visibility. Then after calling gw.execute();
call gw.setVisible(true)
.
为了澄清,请尝试
class GuiWorker extends SwingWorker<Integer, Integer> {
private JFrame frame = new JFrame();
private JDialog dialog = new JDialog(frame, "Loadin data", true);
private JProgressBar progressBar = new JProgressBar();
private Statistics st = new Statistics();
public GuiWorker(GraphEditor editor, Statistics st) {
this.st = st;
Window mainWindow = SwingUtilities.windowForComponent(editor
.getGraphComponent().getParent());
dialog.setSize(400, 200);
int x = mainWindow.getX() + (mainWindow.getWidth() - dialog.getWidth())
/ 2;
int y = mainWindow.getY()
+ (mainWindow.getHeight() - dialog.getHeight()) / 2;
progressBar.setString("Have fun to wait some time...");
progressBar.setStringPainted(true);
progressBar.setIndeterminate(true);
dialog.add(progressBar);
dialog.setModal(true);
dialog.setLocation(x, y);
}
@Override
protected Integer doInBackground() throws Exception {
st.loadInitialData();
return 0;
}
@Override
protected void done() {
dialog.setVisible(false);
JLabel label = new JLabel("Task Complete");
dialog.getContentPane().remove(progressBar);
dialog.getContentPane().add(label);
dialog.getContentPane().validate();
dialog.setVisible(false);
}
public void setVisible(boolean visible) {
dialog.setVisible(visible);
}
}
和
mainTabs.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
switch (mainTabs.getSelectedIndex()) {
case 0:
case 1:
case 2: // stats tab
GuiWorker gw = new GuiWorker(editor,st);
gw.execute();
gw.setVisible(true);
break;
default:
break;
}
}
});
这篇关于SwingWorker,未调用done()方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!