JProgressBar too fast

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-28 05:20:37

问题


I am trying to add a progress bar. everything works and i don't get any error. But the progress bar goes from 0% to 100% without even going through the values between it (I mean it's too fast, and the users are unable to see the progress bar blocks filling in)

pr = new JProgressBar();

            pr(0);
            pr(true);
..

public void iterate(){

        while (i<=20000){
            pr.setValue(i);
            i=i+1000;
            try{
                Thread.sleep(150);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

When i button is clicked i call the iterate() method, and i expect it to update the progress bar progressively. instead it pauses for a while and then displays a full progress bar.

How can i solve this ?

2.) I don't like the default blue color of the progress bar tabs. I need to change the color. I tried pr.setForeground(Color.GRAY); pr.setBackground(Color.RED); But it didn't work.


回答1:


The problem is, you're trying to update the progress within the context of the Event Dispatching Thread.

This basically means that while you are in you loop, the EDT is unable to process any paint request you are making.

What you need to do is some how offload the work to a separate thread and update the progress bar as needed. The problem with this, is you should never update the UI from any thread other then the EDT.

But don't despair, you have a number of options, the best is using a Swing Worker

Updated with example

public class SwingWorkerProgress {

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

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

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JProgressBar pbProgress;
        private JButton start;

        public TestPane() {

            setBorder(new EmptyBorder(10, 10, 10, 10));
            pbProgress = new JProgressBar();
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(4, 4, 4, 4);
            gbc.gridx = 0;
            gbc.gridy = 0;
            add(pbProgress, gbc);

            start = new JButton("Start");
            gbc.gridy++;
            add(start, gbc);

            start.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    start.setEnabled(false);
                    ProgressWorker pw = new ProgressWorker();
                    pw.addPropertyChangeListener(new PropertyChangeListener() {

                        @Override
                        public void propertyChange(PropertyChangeEvent evt) {
                            String name = evt.getPropertyName();
                            if (name.equals("progress")) {
                                int progress = (int) evt.getNewValue();
                                pbProgress.setValue(progress);
                                repaint();
                            } else if (name.equals("state")) {
                                SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
                                switch (state) {
                                    case DONE:
                                        start.setEnabled(true);
                                        break;
                                }
                            }
                        }

                    });
                    pw.execute();
                }
            });

        }
    }

    public class ProgressWorker extends SwingWorker<Object, Object> {

        @Override
        protected Object doInBackground() throws Exception {
            int i = 0;
            int max = 2000;

            while (i < max) {
                i += 10;
                int progress = Math.round(((float)i / (float)max) * 100f);
                setProgress(progress);
                try {
                    Thread.sleep(25);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            return null;
        }
    }
}



回答2:


Why do you iterate in i=i+1000;? Please try something like this:

public void iterate(){

        int i = 0;

        while (i<=100){
            pr.setValue(i);
            i=i+10;
            try{
                Thread.sleep(150);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
}

Also you should use a SwingWorker or at least an extra Thread, but that was mentioned before.



来源:https://stackoverflow.com/questions/13846887/jprogressbar-too-fast

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!