不确定的 JProgressBar Popup/modal 对话框不移动

Indeterminate JProgressBar Popup/modal dialog not moving

我不明白为什么在下面的代码中进度条不动:

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

JDialog 应该在 UI 线程上执行并且进度条应该从左向右移动? 谢谢

编辑:

问题不在代码上,之前,我创建了一个自定义的 JProgressBar,并且修改了重绘间隔和循环时间默认值... 自定义 Jprogress 正在设置:

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

默认设置为:

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

对我来说,我有两个解决方案:

1 / 我每次都定义了周期和间隔,以确保具有正确的值

2 / 我到处都用一样的进度条

我认为解决方案 2 是最好的,但我想知道解决方案一是否也是一个好的解决方案。

  1. 您已将 JProgressBar 设置为不确定的,因此您不应期望对其进行从左到右的更改。根据教程和 API,该条会前后移动
  2. 即使你不这样做,你也永远不会设置它的值,所以它永远不会改变。

如果您想要从左到右稳定地移动并取得进展:

  1. 不要将进度条设置为不确定的。随它去吧
  2. 随着工作人员的进步设置它的价值。这通常是使用添加到 worker 的 PropertyChangeListener 完成的,然后在 worker 中设置进度 属性,并在 listener 中监听它。

两者的例子:

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