2010-04-28 78 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是Main类中的JProgressBar对象。

如何更新它的价值?(进度)

在运行上面的代码()无法看到PBAR。

回答

3

始终遵守摆动的规则

一旦Swing组件已经实现,所有的代码,可能应该在事件派发执行对组件的状态影响或依赖线。

你可以做的是创建一个观察者来更新你的进度条 - 如 - 在这个例子中,你想显示点击按钮时加载的数据的进度。 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()); 
    } 
} 

无耻插件更新:这是从source from my demo project 随意浏览更多的细节。

0

你不应该在事件派发线程之外做任何Swing的东西。要访问它,你需要在运行时用你的代码创建一个Runnable,然后把它传递给SwingUtilities.invokeNow()或SwingUtilities.invokeLater()。问题是我们需要延迟JProgressBar检查以避免干扰Swing线程。为此,我们需要一个Timer,它将在其自己的Runnable中调用invokeNow或更高版本。有关更多详细信息,请参见http://www.javapractices.com/topic/TopicAction.do?Id=160

0
  • 有没有必要显式调用pbra.repaint。
  • 更新JProgressBar应通过GUI调度线程完成。

SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
     // Remember to make pbar final variable. 
     pbar.setValue(i); 
    } 
});