2010-04-28 3 views
2

Как я могу обновить JProgressBar.setValue (int) из другого потока? Моя вторая цель - сделать это в наименьшем количестве классов.Обновление JProgressBar из новой темы

Вот код, я прямо сейчас:

// Part of the main class.... 
pp.addActionListener(
     new ActionListener(){ 
      public void actionPerformed(ActionEvent event){ 
       new Thread(new Task(sd.getValue())).start(); 
      } 
     }); 

public class Task implements Runnable { 
    int val; 
    public Task(int value){ 
     this.val = value; 
    } 

    @Override 
    public void run() { 
     for (int i = 0; i <= value; i++){ // Progressively increment variable i 
      pbar.setValue(i); // Set value 
      pbar.repaint(); // Refresh graphics 
      try{Thread.sleep(50);} // Sleep 50 milliseconds 
      catch (InterruptedException err){} 
     } 
    } 
} 

С. является JButton и начинает новый поток, когда JButton нажата.

pbar - объект JProgressBar из основного класса.

Как я могу обновить свою ценность? (Прогресс)

Код выше в перспективе() не может видеть пбар.

ответ

3

Всегда соблюдайте правила Свинг

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

Что вы можете сделать, так это создать наблюдателя, который обновит ваш индикатор выполнения, такой как - в этом случае вы хотите показать ход загрузки данных одним нажатием кнопки. DemoHelper класс реализует Observable и отправляет обновления всем наблюдателям, когда загружается определенный процент данных. Прогресс бар обновляется через public void update(Observable o, Object arg) {

class PopulateAction implements ActionListener, Observer { 

    JTable tableToRefresh; 
    JProgressBar progressBar; 
    JButton sourceButton; 
    DemoHelper helper; 
    public PopulateAction(JTable tableToRefresh, JProgressBar progressBarToUpdate) { 
     this.tableToRefresh = tableToRefresh; 
     this.progressBar = progressBarToUpdate; 
    } 

    public void actionPerformed(ActionEvent e) { 
     helper = DemoHelper.getDemoHelper(); 
     helper.addObserver(this); 
     sourceButton = ((JButton) e.getSource()); 
     sourceButton.setEnabled(false); 
     helper.insertData(); 
    } 

    public void update(Observable o, Object arg) { 
     progressBar.setValue(helper.getPercentage()); 
    } 
} 

Shameless пробки: это от source from my demo project Не стесняйтесь, чтобы получить более подробную информацию.

0

Вы не должны делать никаких качаний за пределами потока сообщений о событиях. Чтобы получить доступ к этому, вам нужно создать Runnable с запущенным вашим кодом, а затем передать его в SwingUtilities.invokeNow() или SwingUtilities.invokeLater(). Проблема в том, что нам нужна задержка в проверке JProgressBar, чтобы избежать заклинивания нити Swing. Для этого нам понадобится таймер, который вызовет invokeNow или позже в своем Runnable. Посмотрите на http://www.javapractices.com/topic/TopicAction.do?Id=160 для более подробной информации.

0
  • Не требуется явно вызывать pbra.repaint.
  • Обновление JProgressBar должно выполняться через поток диспетчеризации графического интерфейса.

SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
     // Remember to make pbar final variable. 
     pbar.setValue(i); 
    } 
}); 
Смежные вопросы