SwingWorker不会在很长的过程中更新

时间:2018-09-12 10:12:06

标签: java multithreading swing swingworker jprogressbar

我正在使用SwingWorker和

  • 当过程不太繁琐时(例如包含62个元素的“ trams”列表),它将完美地更新JProgressBar
  • 当过程很繁重时,它不会更新JProgressBar(我用100k个元素进行了测试,它最终将使用2M +个元素)

在我的ProgressWorker类下面

@Override
protected Object doInBackground() throws Exception {
    // TODO Auto-generated method stub


    // here process i skipped


    for (Trame t : trames) {
        float progress = (float)FileRW.tramescounter/FileRW.maxtrames;
        progress = progress*100;
        int p = (int) progress;
        setProgress(p);
        System.out.println(getProgress()+"+p"+" ---- progress"+p+" ---- double"+progress);
        Thread.sleep(25);

        FileRW.tramescounter++;


        // here process i skipped

    }

    // here process i skipped

    return null;

}   

此外,我的控制器类:

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();
            Vue.bar.setValue(progress);
            Vue.bar.repaint();
        } else if (name.equals("state")) {
            SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
            switch (state) {
                case DONE:
                    Vue.lastButton.setEnabled(true);
                    if (Vue.check.isSelected()) {
                        if (Desktop.isDesktopSupported()) {
                            Desktop desktop = Desktop.getDesktop();
                            try {
                                desktop.open(new File(Constants.FICHIER_LOG2));
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }

                    Vue.filesInDirectory = null;
                    Vue.fileLabel.setText(Constants.PAN1_LABEL);
                    break;
                default:
                    break;
            }
        }
    }

});
pw.execute();

2 个答案:

答案 0 :(得分:0)

有一个可运行的示例(基于您的上下文外代码)可以工作,所以我的猜测是,不是SwingWorker有问题,而是您未共享的部分代码

请考虑提供一个Minimal, Complete, and Verifiable example来证明您的问题,直到您这样做为止,这是我们可能为您提供的所有帮助

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import static javax.swing.SwingWorker.StateValue.DONE;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

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

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

    public class TestPane extends JPanel {

        private JProgressBar pb = new JProgressBar(0, 100);

        public TestPane() {
            setLayout(new GridBagLayout());
            add(pb);
            BadWorker pw = new BadWorker();
            pw.addPropertyChangeListener(new PropertyChangeListener() {

                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    String name = evt.getPropertyName();
                    if (name.equals("progress")) {
                        int progress = (int) evt.getNewValue();
                        pb.setValue(progress);
                    } else if (name.equals("state")) {
                        SwingWorker.StateValue state = (SwingWorker.StateValue) evt.getNewValue();
                        switch (state) {
                            case DONE:
                                System.out.println("All done where");
                                break;
                        }
                    }
                }

            });
            pw.execute();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.dispose();
        }

    }

    public class BadWorker extends SwingWorker<Object, Object> {

        @Override
        protected Object doInBackground() throws Exception {
            int count = 0;
            int max = 10000;
            do {
                count++;
                float progress = (float) count / max;
                progress = progress * 100;
                int p = (int) progress;
                setProgress(p);
                System.out.println(getProgress() + "+p" + " ---- progress" + p + " ---- double" + progress);
                Thread.sleep(5);
                // here process i skipped
            } while (getProgress() < 100);

            // here process i skipped
            return null;
        }
    }
}

答案 1 :(得分:0)

好吧,没想到问题不是我所期望的

就在我写的代码的第一部分里面

Vue.bar.setMaximum(trames.size());

进一步

float progress = (float)FileRW.tramescounter/FileRW.maxtrames;
progress = progress*100;
int p = (int) progress;
setProgress(p);

在控制器类中

Vue.bar.setValue(progress);

但是在ProgressWorker中设置的进度值为0到100

我的最大ProgressBar值为100K,但0 <进度值<100,

没有进展是正常的