JProgressBar не обновляется в for-l oop при загрузке изображений - PullRequest
0 голосов
/ 19 июня 2020

Я программирую небольшой инструмент, чтобы применить фильтры к большому количеству изображений. Я хочу добавить индикатор выполнения при загрузке изображений. Для этого я написал здесь этот простой код:

            //Set up Progressbar 
            int pictureCount = 0;
            for (File file : chooser.getSelectedFile().listFiles(isImage)) {
                pictureCount++;
            }
            progressBar.setMinimum(0);
            progressBar.setMaximum(pictureCount);


            //Load all the Images and updating Progressbar
            for (File file : chooser.getSelectedFile().listFiles(isImage)) {
                BufferedImage bi = ImageIO.read(file);
                tilesNew.add(bi);
                progressBar.setValue(progressBar.getValue() + 1);
            }

К сожалению, индикатор выполнения обновляется только в конце l oop. поэтому он показывает 0% все время, а затем сразу 100% после того, как программа загрузила все изображения в течение нескольких секунд.

До сих пор я пытался использовать frame.revalidate(), frame.repaint() и Thread.sleep() в l oop. Все безуспешно.

Ответы [ 2 ]

1 голос
/ 19 июня 2020

Я давно не использовал Swing, но похоже, что вы делаете что-то неправильно, обычно обнаруживаемое на любой платформе с GUI.

Кажется, ваш код читает большие файлы в основной поток (UI) .

UI будет обновлен, когда основной поток не занят. Однако основной поток всегда будет занят, пока он обрабатывает изображение.

Вы должны создать новый Thread, который обрабатывает файлы и изображения, а затем созданный поток должен передать его основному поток для обновления пользовательского интерфейса каждый раз, когда processBar необходимо обновить.

Вот несколько помощников в Swing для поддержки многопоточности:
https://stackabuse.com/how-to-use-threads-in-java-swing/

0 голосов
/ 19 июня 2020

Вот быстрая демонстрация использования JProgressBar.

  • Я использую таймер для имитации выполнения некоторой работы.
  • Когда индикатор выполнения обновляется, вызывается ChangeListener и я делаю перерисовку.
  • Убедитесь, что вы не читаете свой файл и не обновляете индикатор выполнения, пока все еще находитесь в EDT.
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.Timer;

public class ProgressBarDemo extends JPanel {
    JFrame frame;
    final static int WIDTH = 200;
    final static int HEIGHT = 30;

    public ProgressBarDemo() {
        frame = new JFrame();
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(this);
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new ProgressBarDemo().startUp();
    }

    public void startUp() {
        JProgressBar p = new JProgressBar(0, 100);

        // every 200 milliseconds, add one to the JProgressBar
        Timer t =
                new Timer(200, (ae) -> p.setValue(p.getValue() + 1));

        // invoked when the JProgressBar changes.  Calls repaint.
        p.addChangeListener((ce) -> frame.repaint());
        add(p);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        t.start();
    }
}

...