JProgressBar不会在循环内更新

时间:2015-04-19 09:19:16

标签: java swing jprogressbar

我目前正在自学Java。我一直在尝试JRadioButton s,JcomboBox等不同的事情。现在,我尝试使用JProgressBar但它似乎并不是工作正常。

相关的代码:

JProgressBar progress;
JButton button;     //Fields of the class

progress=new JProgressBar(JProgressBar.HORIZONTAL,0,100);
button=new JButton("Done");    //Done from methods

progress.setValue(0);
progress.setStringPainted(true);
progress.setBorderPainted(true);  //Also done from methods

button.addActionListener(this);   //Also done from methods

单击button时,我想显示JProgressBar从0%到100%。以下是actionPerformed方法的相关部分:

public void actionPerformed(ActionEvent e)
{

        for(int i=0;i<=progress.getMaximum();i++)
        {
            progress.setValue(i);
            /*try{
                Thread.sleep(10);
            }catch(InterruptedException ex)
            {
                System.err.println("An error occured:"+ex);
                ex.printStackTrace();
            }*/
        }


        progress.setValue(progress.getMinimum());
}

我已将progressbutton添加到JPanel中,并将该面板添加到我使用setVisible(true);的JFrame中。

问题在于,每当我按下JButton button时,JProgressBar progress都不会从0%变为100%。相反,没有任何反应。如果我取消注释try...catch阻止,然后按button,程序就会冻结&#34;一会然后继续这一次,JProgressBar保持在0%,我从未看到它在移动。我在repaint();阻止之后尝试了try...catch,但同样的事情发生了。

我已尝试添加

System.out.println(i+"");

for中的actionPerformed循环内,并且在终端中打印的数字为0到100。所以,我确定循环运行。

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:4)

  • Swing是单线程的,

  • 所有更新必须在EDT上完成,

  • 当前EDT中的所有事件都在GUI中绘制,

  • Thread.sleep用于锁定EDT中事件的执行,在执行Thread.sleep的所有锁定之后,可以在for_loop的末尾绘制重绘,更多信息在Oracle trail中执行 - { {3}}和Concurency in Swing


如果ActionListener内的所有事件都被执行,那么应该执行AWT(Swing)监听器<{1>}的输出,然后只执行actionPerformed,如果有的话无关紧要是progress.setValue(progress.getMinimum());还是不

Thread.sleep

  • 使用public void actionPerformed(ActionEvent e) -> progress.setValue(progress.getMinimum()); SwingWorkerRunnable#Thread包裹在progress.setValue(i);

  • 更快地发布invokeLater / SSCCE,简短,可运行,可编辑

答案 1 :(得分:1)

您必须将以下代码放入新线程

public void actionPerformed(ActionEvent e)
{

    for(int i=0;i<=progress.getMaximum();i++)
    {
        progress.setValue(i);
        /*try{
            Thread.sleep(10);
        }catch(InterruptedException ex)
        {
            System.err.println("An error occured:"+ex);
            ex.printStackTrace();
        }*/
    }


    progress.setValue(progress.getMinimum());
}

像这样的东西

public void actionPerformed(ActionEvent e)
{
    new Thread(){
        public void run(){
            for(int i=0;i<=progress.getMaximum();i++)
            {
                progress.setValue(i);
                try{
                    sleep(10);
                }catch(InterruptedException ex)
                {
                    System.err.println("An error occured:"+ex);
                    ex.printStackTrace();
                }
            }
        }
    }.start();
    progress.setValue(progress.getMinimum());
}

未经过测试,progress实例可能是final

答案 2 :(得分:1)

就你的代码而言,它看起来都是合法的。无论是否启动线程,似乎都没有任何问题。

我建议您删除此内容:

//for testing purposes
progress.setValue(progress.getMinimum());

然后设置进度条50的值。删除线程代码,并使用条件为“&lt; 50”的for循环。

如果一切都失败了,这肯定会有所启发:JProgress Bar: Working!

让我知道结果。