2017-02-19 63 views
-2

我已经编写了使用swing libs的代码,当添加一个actionlistener时,不会更新progressBar。java swing progressBar

没有按钮和动作侦听器,它的工作效果很好。如何尽可能简单而干净地强制progressBar更新?附加的代码是一个容易理解的例子,总结了我的问题。如果你注释掉一个ActionPerformed方法并从main执行程序,它就可以正常工作。

不要只是在没有解释的情况下粘贴代码。

PS:我已经看到了这一点:swing progressBar threading

public class Okno { 

    private JProgressBar progressBar = new JProgressBar(0,306); 
    JFrame f = new JFrame("JProgressBar Sample"); 
    JButton b = new JButton("start"); 
    ActionListener a = new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      barupdate(); 
     } 
    }; 


    private void barupdate(){ 
     for(int p = 1; p<308;p=p+2){ 
      System.out.println(p); 

      progressBar.setValue(p); 

       try { 
         Thread.sleep(50); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
     } 
} 

private Okno(){ 

    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    progressBar.setStringPainted(true); 

    f.add(progressBar, BorderLayout.SOUTH); 
    f.add(b, BorderLayout.NORTH); 
    b.addActionListener(a); 
    f.setSize(300, 300); 
    f.setVisible(true); 

} 

public static void main(String[] args) { 
    Okno okno = new Okno(); 
} 
} 
+0

这是一个非常普遍的问题,它通常以相同的方式解决,在这种情况下最好的解决方案通常使用'SwingWorker',[例如](http://stackoverflow.com/questions/12020949/jprogressbar-isnt -progressing/12021971#12021971)。您还可以查看[并发中的摆动](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)以获取有关该问题的更多详细信息。在大多数情况下,使用另一个'Thread'本身并不是最好的选择,因为Swing不是线程安全的,你必须采取额外的预防措施来更新用户界面,这是SwingWorker免费提供给你的;) – MadProgrammer

+0

@ MadProgrammer,“在这种情况下,最好的解决方案通常是使用SwingWorker ......你应该看看Swing中的并发性,” - 希望我能想到这一点。 – camickr

+0

@camickr这个问题应该被关闭,但是我知道你有这样的问题,所以我留下了我的评论(支持你的回答),并且离开 – MadProgrammer

回答

1

问题是你有一个循环,你正在调整正从一个动作侦听器称为进度条设置。问题是,直到听众完成之后,条才会更新。所以你将不会得到更新。不仅如此,当你处于动作侦听器中时,窗口无法对鼠标点击等作出反应,因此你会陷入gu gu。

所以处理这个问题的最好方法是在动作监听器中创建一个swing定时器,并将更新按钮的代码放在那里,然后在动作侦听器中启动定时器。

计时器应该只更新一次吧。并且你应该允许摆动计时器将被多次调用以发挥重复性的部分。所以你不想在你的代码中有任何循环。

+0

感谢指向我在一个方向......我会报告它是如何去的,并发布代码 –

0
Thread.sleep(50); 

不要使用Thread.sleep(...)。这将阻止GUI直到循环完成执行时重新绘制自己。可以使用SwingWorker

阅读Swing教程Concurrency in Swing中的部分,其中包含更多信息并包含SwingWorker的工作示例。

另外,请看教程目录。在How to Use ProgressBars上有一节也包含一个工作示例。该教程是查找示例的第一个地方。

+0

代码是一个总结我的问题的例子,而sleep()方法只是为了让程序进度更慢。如果你删除actionlistening代码并从main开始进度条代码,那么它工作正常。 –

+0

我知道。当您从main()开始进度条时,代码将在另一个线程中执行。当您在ActionListener中启动进度条时,代码在作为绘制GUI的线程的'Event Dispatch Thread(EDT)'上执行。所以你需要在一个单独的线程中启动你的进度条,这就是为什么你需要阅读教程以更好地理解Swing如何工作。 '该教程有工作示例'。 – camickr