JProgressBar 不在循环内更新
JProgressBar does not update within the loop
目前正在自学Java。我一直在尝试不同的东西,例如 JRadioButton
s、JcomboBox
es 等。现在,我正在尝试使用 JProgressBar
s,但它似乎无法正常工作。
相关代码:
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());
}
我已将 progress
和 button
添加到 JPanel 中,并将面板添加到我使用 setVisible(true);
.
的 JFrame 中
这里的问题是,每当我按下 JButton button
时,JProgressBar progress
不会从 0% 变为 100%。相反,什么也没有发生。如果我取消注释 try...catch
块,然后按 button
,程序 "freezes" 片刻然后继续。这一次,JProgressBar 也保持在 0%,我从未看到它移动。我也在 try...catch
块之后尝试了 repaint();
但同样的事情发生了。
我试过添加
System.out.println(i+"");
在 actionPerformed
的 for
循环中,这在终端中打印了数字 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());
使用 SwingWorker
或 Runnable#Thread
将 progress.setValue(i);
包裹到 invokeLater
尽快获得更好的帮助 post SSCCE
/MCVE
,简短,可运行,可编译
就您的代码而言,一切看起来都是合法的。无论是否启动线程,似乎都不会出现任何问题。
我建议你删除这个:
//for testing purposes
progress.setValue(progress.getMinimum());
然后让进度条的值为50,去掉线程代码,使用条件为“<50”的for循环。
如果一切都失败了,这肯定会有所启发:JProgress Bar: Working!
让我知道结果。
目前正在自学Java。我一直在尝试不同的东西,例如 JRadioButton
s、JcomboBox
es 等。现在,我正在尝试使用 JProgressBar
s,但它似乎无法正常工作。
相关代码:
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());
}
我已将 progress
和 button
添加到 JPanel 中,并将面板添加到我使用 setVisible(true);
.
这里的问题是,每当我按下 JButton button
时,JProgressBar progress
不会从 0% 变为 100%。相反,什么也没有发生。如果我取消注释 try...catch
块,然后按 button
,程序 "freezes" 片刻然后继续。这一次,JProgressBar 也保持在 0%,我从未看到它移动。我也在 try...catch
块之后尝试了 repaint();
但同样的事情发生了。
我试过添加
System.out.println(i+"");
在 actionPerformed
的 for
循环中,这在终端中打印了数字 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());
使用
SwingWorker
或Runnable#Thread
将progress.setValue(i);
包裹到invokeLater
尽快获得更好的帮助 post
SSCCE
/MCVE
,简短,可运行,可编译
就您的代码而言,一切看起来都是合法的。无论是否启动线程,似乎都不会出现任何问题。
我建议你删除这个:
//for testing purposes
progress.setValue(progress.getMinimum());
然后让进度条的值为50,去掉线程代码,使用条件为“<50”的for循环。
如果一切都失败了,这肯定会有所启发:JProgress Bar: Working!
让我知道结果。