SwingWorker,未调用done()方法 [英] SwingWorker, done() method not called

查看:135
本文介绍了SwingWorker,未调用done()方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这只是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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆