Проблема при создании значений обновления JProgressBar в цикле (с резьбой) - PullRequest
5 голосов
/ 01 марта 2011

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

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

Моя программа содержит несколько классов, Main - это класс, автоматически создаваемый netbeans в режиме JFrame Design , поэтому существуют определенные вещи, такие как static void main и public Main, которые не совсем уверен, что некоторые из его содержания. Под я помещу фрагменты этих методов вместе с моей реализацией потока.

public class Main extends javax.swing.JFrame implements ActionListener, Runnable{
                                          // I added implements ActLis, Runn.....

...

static Main _this;      // I included this variable

...

public static void main(String args[]) {
        Main m = new Main();                               // Added by me
        new Thread(m).start();                             // Added by me
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Main().setVisible(true);
            }
        });
 }

...

public Main() {
        initComponents();
        _this = this;        // Added by me
}


...

// I also included these 2 methods in the class

public void actionPerformed(ActionEvent e) {                                    
    synchronized(this){                                                         
        notifyAll();                                                            
    }                                                                           
}                                                                               

public void run() {                                                             
    try{synchronized(this){wait();}}
    catch (InterruptedException e){}
    progressBar.setValue(50);                                                   
}

...

private void buttonPressed(java.awt.event.MouseEvent evt) {
   for(int i=0; i<=100; i++) {
      for(int j=0; j<=5; j++) {
         // does some work
      }
   run();
   }
}

Все вещи, которые я прокомментировал как I added..., - это вещи, которые я поместил в соответствии с учебными пособиями и ответами, которые я видел в Интернете, но, похоже, ничего не работает, и мне кажется, что я пробовал около миллиона различных комбинаций ...

Заранее спасибо за помощь.

Ответы [ 2 ]

10 голосов
/ 01 марта 2011

Вот несколько оснований, на которые вам стоит обратить внимание, если вы сможете изучить их и понять, почему присутствует каждый фрагмент кода, то я думаю, что это поможет. Не стесняйтесь задавать вопросы в комментариях (хотя я иду спать прямо сейчас!)

Пример:

public class ProgressBarDemo extends JFrame {
    private final JProgressBar progressBar = new JProgressBar(0, 100);
    private int progressCounter = 0;

    public ProgressBarDemo() {
        setContentPane(progressBar);
        setPreferredSize(new Dimension(100, 100));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        new Thread(new Runnable() {
            public void run() {
                while (progressCounter <= 100) {
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            progressBar.setValue(progressCounter++);
                        }
                    });
                    try { Thread.sleep(500); } catch (InterruptedException e) {}
                }
            }
        }).start();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new ProgressBarDemo().setVisible(true);
            }
        });
    }
}

Два разных способа решения проблемы с использованием SwingWorker:

SwingWorker Пример 1:

    ....
    public ProgressBarDemo() {
        setContentPane(progressBar);
        setPreferredSize(new Dimension(100, 100));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();

        SwingWorker<Integer, Void> worker = new SwingWorker<Integer,Void>() {
            public Integer doInBackground() {
                while (progressCounter <= 100) {
                    setProgress(progressCounter++);
                    try { Thread.sleep(500); } catch (InterruptedException e) {}
                }
                return 0;
            }
        };
        worker.addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent event) {
                if ("progress".equals(event.getPropertyName())) {
                    progressBar.setValue((Integer)event.getNewValue());
                }
            }
        });
        worker.execute();
    }
    ....

Пример 2 SwingWorker (не очень красиво, но, тем не менее, интересно):

    ....
    public ProgressBarDemo() {
        setContentPane(progressBar);
        setPreferredSize(new Dimension(100, 100));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();

        new SwingWorker<Integer,Integer>() {
            public Integer doInBackground() { 
                while (progressCounter <= 100) {
                    publish(progressCounter++);
                    try { Thread.sleep(500); } catch (InterruptedException e) {}                    
                }
                return 0;
            }
            public void process(List<Integer> progresses) {
                Integer maxProgress = null;
                for (int progress : progresses) {
                    if (maxProgress == null || progress > maxProgress) {
                        maxProgress = progress;
                    }
                }
                progressBar.setValue(maxProgress);
            }
        }.execute();
    }
    ....
3 голосов
/ 01 марта 2011

В вашем коде есть несколько ошибок: (

  • вы дважды создаете Main, и в итоге вы ожидаете один экземпляр и уведомляете другой.
  • youВы вручную вызываете run (), а также планируете поток, чтобы сделать это тоже ...

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

...