ProgressBar不会在Java中更改其值

时间:2011-04-17 06:36:07

标签: java swing progress-bar

我有奇怪的问题。我设置了一个JProgressBar:

private JProgressBar progressBar;

public void foo()
{
    ...
    progressBar = new JProgressBar(0, 100);
    progressBar.setValue(0);
    progressBar.setStringPainted(true);
    ...
    contentPane.add(progressBar);
    ...
}

但是只有当我把setValue函数放在代码中的某些地方时才会改变,而不是到处都是:

public void foo2()
{
    progressBar.setValue(100); //working
    if(...)
    {
        System.out.println("These instructions are executing"); //working
        progressBar.setValue(0);                                //not working
    }                             
}

那么,我做错了什么?为什么第二条指令不起作用?

2 个答案:

答案 0 :(得分:16)

进度条的值确实已更新。但它不仅仅是在屏幕上。通常,我们在循环中使用进度条。但是,当您处于循环中时,您可能通过单击按钮来强调它,但它不会被绘制。为什么?因为您通过单击按钮来调用它。当您单击按钮时,您为该按钮创建的所有代码都由AWTEventThread执行。这是跟踪所有Swing组件的相同线程,并检查它们是否必须重新绘制。这是让你的JFrame活跃起来的线程。当您悬停按钮并且颜色稍有变化时,它由AWTEventThread完成。

因此,当您在循环中工作时,AWTEventThread无法再更新屏幕。

这意味着有两种解决方案:

  1. (推荐)您应该创建一个执行循环的单独线程。这意味着AWTEventThread可以在必要时更新屏幕(当您致电bar.setValue(...);时)

    public void yourButtonClickMethod()
    {
        Runnable runner = new Runnable()
        {
            public void run() {
            //Your original code with the loop here.
            }
        };
        Thread t = new Thread(runner, "Code Executer");
        t.start();
    }
    
  2. 手动重绘进度条。我总是用bar.repaint();做到这一点,但我想知道它是否会奏效。我虽然是那种方法。如果这不起作用,请尝试:bar.update(bar.getGraphics());

答案 1 :(得分:-1)

即使已经回答了这个问题,我也找到了另一种对我有用的方法。我正在使用swing工作者并使用 propertyChange(null)更新进度条是最简单的解决方案。

只是想提供这种替代方案。