Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwingWorker, done() method not called

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

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: I am sure that done() method is called just when I close the dialog.

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;
                    }
                }
            });
like image 933
Houssem Badri Avatar asked Sep 17 '26 14:09

Houssem Badri


1 Answers

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.

In the event listener you instantiate the GuiWorker and in that constructor you open the dialog by calling dialog.setVisible(true);.

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.

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).

To clarify, try

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

and

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;
                    }
                }
            });
like image 75
Can't Tell Avatar answered Sep 19 '26 04:09

Can't Tell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!