JProgressBar 不在循环内更新

JProgressBar does not update within the loop

目前正在自学Java。我一直在尝试不同的东西,例如 JRadioButtons、JcomboBoxes 等。现在,我正在尝试使用 JProgressBars,但它似乎无法正常工作。

相关代码:

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,程序 "freezes" 片刻然后继续。这一次,JProgressBar 也保持在 0%,我从未看到它移动。我也在 try...catch 块之后尝试了 repaint(); 但同样的事情发生了。

我试过添加

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

actionPerformedfor 循环中,这在终端中打印了数字 0 到 100。所以,我确定循环运行了。

我该如何解决这个问题?

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

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 也许

  • Swing 是单线程的,

  • 所有更新必须在美国东部时间完成,

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

  • Thread.sleep 锁定 EDT 中事件的执行,重绘可以在 for_loop 的末尾绘制,在所有来自 Thread.sleep 的锁定之后已执行,更多在 Oracle trail - Concurency in Swing and EventDispatchThread


AWT (Swing) Listener 的输出 - ActionListener,如果 actionPerformed 中的所有事件都已执行,则应该完成,然后仅执行 progress.setValue(progress.getMinimum());,是否无关紧要有没有Thread.sleep没有

public void actionPerformed(ActionEvent e) -> progress.setValue(progress.getMinimum());

  • 使用 SwingWorkerRunnable#Threadprogress.setValue(i); 包裹到 invokeLater

  • 尽快获得更好的帮助 post SSCCE/MCVE,简短,可运行,可编译

就您的代码而言,一切看起来都是合法的。无论是否启动线程,似乎都不会出现任何问题。

我建议你删除这个:

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

然后让进度条的值为50,去掉线程代码,使用条件为“<50”的for循环。

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

让我知道结果。