SwingWorker не обновляется при длительном процессе

Я использую SwingWorker и

  • Он отлично обновляет JProgressBar, КОГДА процесс не слишком тяжелый (например, список «Trames», содержащий 62 элемента)
  • Он не обновляет JProgressBar, когда процесс тяжелый (я тестировал 100 000 элементов, наконец, он будет работать с 2 миллионами элементов)

Ниже моего класса 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();

person Alex T    schedule 12.09.2018    source источник


Ответы (2)


Есть работающий пример (основанный на вашем внеконтекстном коде), который работает, поэтому я предполагаю, что виноват не SwingWorker, а какая-то часть кода, которой вы не делитесь.

Рассмотрите возможность предоставления минимального, полного и проверяемого примера, который демонстрирует вашу проблему, пока вы этого не сделаете, это почти вся возможная помощь. дать вам

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;
        }
    }
}
person Community    schedule 12.09.2018

Хорошо, неважно, проблема была не той, которую я ожидал

Просто внутри первой части кода, которую я пропустил, я написал

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,

Это было нормально, что это не прогрессировало

person Alex T    schedule 12.09.2018