如何使jprogressbar与我的算法并行运行 [英] How to make a jprogressbar to run in parallel with my algorithm

查看:117
本文介绍了如何使jprogressbar与我的算法并行运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

Java GUI JProgressBar不绘画

可以在main之外的课程中使用进度条吗?

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

I am using Netbeans drag and drop to do an application. I will get input from user and use the input to run my algorithm. The algorithm will take different time to run and then show its result in a new frame. While waiting the algorithm to run, I wish to add in a progress bar. I add in the below code when the user click the button submit input.

    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

进度条确实显示并运行。但是当进度条值更新到结束时,只运行我的算法。我看透其他人的例子,但我真的不明白它是如何运作的。

The progressbar do show up and run.But when the progress bar value is update until the end, only my algorithm run. I see through others example, but I not really understand how it works.

有人可以告诉我哪里出错吗?

Can someone tell me where I got wrong?

推荐答案

Swing中一些最重要的概念是

Some of the most important concepts in Swing are

不要执行任何长期事件调度线程(ETD)中的运行/阻塞操作。这将导致UI显示为冻结且无响应。很好的是,你似乎明白这一点。

DO NOT perform any long running/blocking operations within the Event Dispatching Thread (ETD). This will cause the UI to appear "frozen" and non-responsive. What's nice is, you seem to understand this.

不要从任何线程创建或修改任何ui组件,然后是EDT。你不是这样做的。

DO NOT create or modify ANY ui component from any thread OTHER then the EDT. You're not doing this.

你最好的理由是利用 SwingWorker ,这允许您执行长时间运行的操作,同时向听众提供进度反馈。

You best cause of action is to take advantage of the SwingWorker, this allows you to perform long running operations, while providing progress feedback to listeners.

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

You're other choice would be to use a ProgressMonitor or, if you're really desperate, use SwingUtilities#invokeLater(Runnable), but, I'd really encourage you to use SwingWorker instead ;)

这篇关于如何使jprogressbar与我的算法并行运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆