Проблема с созданием значений обновления JProgressBar в Loop (Threaded)

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

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

Моя программа содержит несколько классов, 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..., — это вещи, которые я разместил в соответствии с руководствами и ответами, которые я видел в Интернете, но, похоже, ничего не работает, и кажется, что я пробовал около миллиона различных комбинаций...

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


person Fabian    schedule 28.02.2011    source источник


Ответы (2)


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

Пример:

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:

Пример 1 SwingWorker:

    ....
    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();
    }
    ....
person Mike Tunnicliffe    schedule 01.03.2011
comment
вау, приятель, это действительно много значит для меня все время и мысль, которую ты вложил, чтобы помочь мне понять многопоточность и решить проблему. Рад сообщить, что мне удалось это сделать на вашем первом примере. Где мне поставить тройную галочку как лучший гребаный ответ? - person Fabian; 01.03.2011

В вашем коде что-то не так :(

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

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

person iluxa    schedule 28.02.2011
comment
+1 iluxa прав. Рассмотрим SwingWorker, как предлагается в этом примере. - person trashgod; 01.03.2011