Search code examples
javaswingjprogressbar

Indeterminate JProgressBar Popup/modal dialog not moving


I don't understand why the progress bar does not move in the following code:

JDialog dlgProgress = new JDialog(InterfaceYadis.frameInterface, "Veuillez patienter...", true);
JLabel lblStatus = new JLabel("Test");

JProgressBar pbProgress = new JProgressBar(0, 100);
pbProgress.setIndeterminate(true);

dlgProgress.add(BorderLayout.NORTH, lblStatus);
dlgProgress.add(BorderLayout.CENTER, pbProgress);
dlgProgress.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
//dlgProgress.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dlgProgress.setSize(300, 90);
dlgProgress.setLocationRelativeTo(null);


SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>() {
    @Override
    protected Void doInBackground() throws Exception {
        Thread.sleep(2500);
        return null;
    }

    @Override
    protected void done() {
        dlgProgress.dispose();
    }
};

sw.execute();
dlgProgress.setVisible(true);

The JDialog should be executed on UI thread and the progress bar should move from left to right ? Thanks.

EDIT:

The problem is not on the code, before, i have created a custom JProgressBar and i have modified the repaint interval and cycle time defaults... Custom Jprogress was setting :

UIManager.put("ProgressBar.repaintInterval", new Integer(50));
UIManager.put("ProgressBar.cycleTime", new Integer(100));

The default setting is :

INTERVAL = UIManager.getInt("ProgressBar.repaintInterval"); // = 50
CYCLETIME = UIManager.getInt("ProgressBar.cycleTime"); // = 3000

For me, I have two solutions:

1 / I defined the cycle and the interval each time to be sure to have the right values

2 / I use the same everywhere progressbar

I think the solution 2 is the best, but I like to know if the solution one can be a good solution too.


Solution

    1. You've set the JProgressBar to be indeterminate, so you shouldn't expect left to right changes to it. Rather per the tutorial and the API, the bar will move back and forth
    2. And even if you don't do this, you never set its value, so it will never change.

    If you want steady left to right movement with progress:

    1. Don't set the progress bar to be indeterminate. Leave it be
    2. Set it's value as your worker progresses. This is often done using a PropertyChangeListener added to the worker and then within the worker setting the progress property, and within the listener, listening to it.

    For example of both:

    import java.awt.BorderLayout;
    import java.awt.Dialog.ModalityType;
    import java.awt.Dimension;
    import java.awt.Window;
    import java.awt.event.ActionEvent;
    import java.awt.event.KeyEvent;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class ProgressBarEg extends JPanel {
        public ProgressBarEg() {
            add(new JButton(new ShowDialogAction("Show Indeterminant Dialog", KeyEvent.VK_I, true)));
            add(new JButton(new ShowDialogAction("Show Determinant Dialog", KeyEvent.VK_D, false)));
            setPreferredSize(new Dimension(500, 350));
        }
    
        private class MyWorker extends SwingWorker<Void, Void> {
    
            private static final int DELTA_PROGRESS = 1;
            private static final long SLEEP_TIME = 40;
    
            @Override
            protected Void doInBackground() throws Exception {
                int progress = getProgress();
                while (progress < 100) {
                    progress += DELTA_PROGRESS;
                    progress = Math.min(progress, 100);
                    setProgress(progress);
                    Thread.sleep(SLEEP_TIME);
                }
                return null;
            }
        }
    
        private class ShowDialogAction extends AbstractAction {
            JDialog dlgProgress;
            private boolean indeterminant;
            JProgressBar pbProgress = new JProgressBar(0, 100);
    
            public ShowDialogAction(String name, int mnemonic, boolean indeterminant) {
                super(name);
                putValue(MNEMONIC_KEY, mnemonic);
                this.indeterminant = indeterminant;
            }
    
            @Override
            public void actionPerformed(ActionEvent e) {
                if (dlgProgress == null) {
                    Window window = SwingUtilities.getWindowAncestor(ProgressBarEg.this);
                    dlgProgress = new JDialog(window, "Veuillez patienter...", ModalityType.APPLICATION_MODAL);
                    JLabel lblStatus = new JLabel("Test");
    
                    if (indeterminant) {
                        pbProgress.setIndeterminate(true);
                    } else {
                        pbProgress.setStringPainted(true);
                    }
    
                    dlgProgress.add(BorderLayout.NORTH, lblStatus);
                    dlgProgress.add(BorderLayout.CENTER, pbProgress);
                    dlgProgress.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                    //dlgProgress.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
                    dlgProgress.setPreferredSize(new Dimension(300, 90));
                    dlgProgress.setLocationRelativeTo(null);
                    dlgProgress.pack();
                }
    
                SwingWorker<Void, Void> sw = new MyWorker();
                sw.addPropertyChangeListener(new PropertyChangeListener() {
    
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        if (evt.getPropertyName().equalsIgnoreCase("progress")) {
                            pbProgress.setValue((Integer) evt.getNewValue()); 
                        } else if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
                            dlgProgress.dispose();
                        } 
                    }
                });
    
                sw.execute();
                dlgProgress.setVisible(true);
    
            }
        }
    
        private static void createAndShowGui() {
            ProgressBarEg mainPanel = new ProgressBarEg();
    
            JFrame frame = new JFrame("ProgressBarEg");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.getContentPane().add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createAndShowGui();
                }
            });
        }
    }