【问题标题】:How to make a jprogressbar to run in parallel with my algorithm [duplicate]如何使 jprogressbar 与我的算法并行运行 [重复]
【发布时间】:2012-12-15 08:24:28
【问题描述】:

可能重复:
Java GUI JProgressBar not painting
Can a progress bar be used in a class outside main?

我正在使用 Netbeans 拖放来做一个应用程序。我将从用户那里获得输入并使用输入来运行我的算法。该算法将需要不同的时间来运行,然后在新的帧中显示其结果。在等待算法运行时,我希望添加一个进度条。 当用户单击按钮提交输入时,我添加了以下代码。

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {   

    final JProgressBar bar = new JProgressBar(0,250000);
    bar.setValue(1000);
    bar.setIndeterminate(false);
    JOptionPane jO = new JOptionPane(bar);

    Thread th = new Thread(){

    public void run(){
        for(int i = 1000 ; i < 250000 ; i+=10000){
           bar.setValue(i);
            try {
                Thread.sleep(100);
           } catch (InterruptedException e) {
            }
        }
    }
};
th.start();

final JDialog dialog = jO.createDialog(jO,"Experiment X");
dialog.pack();
dialog.setVisible(true);

//Algorithm goes here

进度条确实显示并运行。但是当进度条值更新到最后时,只有我的算法运行。我看过别人的例子,但我不太明白它是如何工作的。

谁能告诉我哪里出错了?

【问题讨论】:

标签: java swing jprogressbar


【解决方案1】:

Swing 中一些最重要的概念是

请勿在事件调度线程 (ETD) 中执行任何长时间运行/阻塞的操作。这将导致 UI 出现“冻结”且无响应。好在,你似乎明白这一点。

请勿从除 EDT 之外的任何线程创建或修改任何 ui 组件。你没有这样做。

您最好的行动原因是利用SwingWorker,这允许您执行长时间运行的操作,同时向侦听器提供进度反馈。

public class TestProgress {

    public static void main(String[] args) {
        new TestProgress();
    }

    public TestProgress() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                ProgressPane progressPane = new ProgressPane();
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(progressPane);
                frame.setSize(200, 200);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

//                progressPane.doWork();
            }
        });
    }

    public class ProgressPane extends JPanel {

        private JProgressBar progressBar;
        private JButton startButton;

        public ProgressPane() {

            setLayout(new GridBagLayout());
            progressBar = new JProgressBar();

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            add(progressBar, gbc);
            startButton = new JButton("Start");
            gbc.gridy = 1;
            add(startButton, gbc);

            startButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    startButton.setEnabled(false);
                    doWork();
                }
            });

        }

        public void doWork() {

            Worker worker = new Worker();
            worker.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if ("progress".equals(evt.getPropertyName())) {
                        progressBar.setValue((Integer) evt.getNewValue());
                    }
                }
            });

            worker.execute();

        }

        public class Worker extends SwingWorker<Object, Object> {

            @Override
            protected void done() {
                startButton.setEnabled(true);
            }

            @Override
            protected Object doInBackground() throws Exception {

                for (int index = 0; index < 1000; index++) {
                    int progress = Math.round(((float) index / 1000f) * 100f);
                    setProgress(progress);

                    Thread.sleep(10);
                }

                return null;
            }
        }
    }
}

您的其他选择是使用ProgressMonitor,或者,如果您真的很绝望,请使用SwingUtilities#invokeLater(Runnable),但是,我真的鼓励您改用SwingWorker ;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    • 2016-02-15
    • 2020-12-31
    • 1970-01-01
    • 2014-04-23
    • 2023-04-07
    相关资源
    最近更新 更多