Java ProgressMonitor не работает

Мой код, как показано ниже, не работает, может кто-нибудь сказать мне, почему? Пожалуйста, исправьте мой код, я новичок в Java. Кроме того, я ищу "компонент панели загрузки", что-то вроде ProgressMonitor но может быть более привлекательным, и который оживляет лучше. Пожалуйста, предложите мне, если кто-то использовал такие вещи раньше.

public class Main extends JFrame {

    private JPanel contentPane;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Main frame = new Main();
                    frame.setVisible(true);

                    ProgressMonitor pm = new ProgressMonitor(frame, "Loading...", 
                            "waiting...",
                            0, 100000);

                    for (int i = 0 ; i < 100000 ; i ++){

                        pm.setProgress(i);
                        pm.setNote("Testing");
                        System.out.println(i);

                        Thread.sleep(1000);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Main() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);
    }

}

3 ответа

Решение

Как уже отмечалось @Mark Rotteveel, вы удерживаете EDT (Thread Dispatch Thread) занятым. Учебное пособие "Как отображать индикаторы выполнения / мониторы" содержит ценную информацию и примеры кода.

Но в основном все сводится к переносу ваших вычислений в рабочий поток (например, с использованием SwingWorker) и показывая ProgressMonitor на EDT. Это до рабочего потока, чтобы указать ProgressMonitor какой прогресс уже достигнут.

А вот прямая ссылка на пример кода этого учебника, который ясно показывает, как работа выполняется в SwingWorker расширение (Task класс в этом примере), и как ProgressMonitor обновляется путем добавления PropertyChangeListener к SwingWorkerгде слушатель передает прогресс в ProgressMonitor,

Я также предложил бы прочитать учебник Concurrency in Swing, который содержит больше информации о том, как обращаться Threads в сочетании с Swing, и почему вы не можете / не должны делать тяжелые вычисления на EDT

В Swing поток событий - это то, что изменяет и обновляет графический интерфейс. Поток событий занят этим циклом for и sleep, поэтому он не может обновить GUI. Все, что вы делаете в потоке событий, должно быть недолгим. Все остальное должно быть удалено из потока событий.

Так что вам нужно переместить этот цикл for из потока событий.

1. Считайте это эмпирическим правилом: пользовательский интерфейс работает в потоке пользовательского интерфейса, а не-пользовательский интерфейс - в не-пользовательском потоке.

2. Поток диспетчера событий (EDT) - это поток пользовательского интерфейса, поэтому вы должны поддерживать интенсивную работу, не связанную с пользовательским интерфейсом, в отдельном потоке вне EDT.

3. Вы можете сделать это двумя способами.....

я. Создайте отдельную тему для этого.

II. Используйте SwingWorker для синхронизации не-пользовательского интерфейса и потока пользовательского интерфейса.

4. Всегда оставляйте метод main() только для того, чтобы JFrame был виден в EDT.

например:

public static void main(String[] args){

       EventQueue.invokeLater(new Runnable(){

         public void run(){

             myframe.setVisible(true);

            }
         }
      }

Посмотрите на этот сайт рабочий пример SwingWorker:

http://www.kodejava.org/examples/381.html

Другие вопросы по тегам