【问题标题】:SwingWorker, done() method not calledSwingWorker,未调用 done() 方法
【发布时间】:2014-04-21 09:59:24
【问题描述】:

这只是 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 在我强行关闭之前从不隐藏的问题(任务完成后必须隐藏)。 我注意到loadInitialData() 方法是一种从我的DB 收集一些统计信息的方法,这需要几秒钟。

更新:我确信在我关闭dialog 时会调用done() 方法。

更新: 我使用 GuiWorker 的地方在这里:

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;
                    }
                }
            });

【问题讨论】:

  • 请将代码贴在你使用 GuiWorker 的地方
  • @Can'tTell 查看更新:)

标签: java multithreading swing swingworker


【解决方案1】:

所有摇摆事件都在Event Dispatch Thread 内运行。因此,您添加到 mainTabsChangeListener 在事件调度线程中运行。

在事件侦听器中实例化GuiWorker,并在该构造函数中通过调用dialog.setVisible(true); 打开对话框。

您的 JDialog 实例是 modal 并且在模式对话框上调用 setVislbe(true) 将阻塞调用线程,在您的情况下是事件调度线程。因此,在关闭对话框之前,不会调用 gw.execute();。这就是为什么在您关闭对话框之前不会调用您的 done 方法的原因。

为了使您的代码正常工作,您可以尝试不在构造函数中调用 setVisible(true),而是提供来自 GuiWorker 的方法来设置对话框的可见性。然后在调用gw.execute(); 之后调用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;
                    }
                }
            });

【讨论】:

    猜你喜欢
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-07
    • 2015-07-21
    • 2014-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多