这是一个小例子:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
int x = 0;
while (jProgressBar1.getValue() < 100) {
try {
Thread.sleep(50);
x++;
jProgressBar1.setValue(x);
jProgressBar1.repaint();
} catch (InterruptedException ex) {
Logger.getLogger(MainWindow.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(jProgressBar1.getValue());
}
}
System.out.println(jProgressBar1.getValue());
返回IDE输出的数字,但jProgressBar1不会绘制此值。这段代码出了什么问题?请帮忙。
答案 0 :(得分:1)
永远不要在Swing线程中使用Thread.sleep()。改为使用javax.swing.Timer。
示例:
private void jButton1ActionPerformed(ActionEvent evt) {
final Timer t = new Timer(50, new ActionListener() {
public void actionPerformed(ActionEvent e) {
jProgressBar1.setValue(jProgressBar1.getValue() + 1);
if (jProgressBar1.getValue() == 100) {
((Timer) e.getSource()).stop();
}
}
});
t.start();
}
答案 1 :(得分:-1)
问题是你在正在做“工作”的同一个线程中调用.repaint()
(Thread.sleep)。 "repaint() does not invoke paint() directly. It schedules a call to an intermediate method, update(). Finally, update() calls paint()..."。这意味着您正在安排一堆repaint()
次呼叫,但它们未被处理。我还打赌,一旦值达到100,进度条跳转到已满,这是因为主线程已经结束并且所有repaint()
调用最终都被处理。
为了使jProgressBars工作,你必须让他们的重新绘制发生在与你正在工作的线程不同的线程中(特别是应该在不同的线程中) - 对于大多数Swing更新也是如此。 。在调用代码之前尝试在新线程中启动此Runnable:
public class ProgressBarPainter implements Runnable{
public JProgressBar jProgressBar1;
public void run(){
while(true){
try {
Thread.sleep(50);
jProgressBar1.repaint();
} catch (InterruptedException ex) {
break;
}
}
}
}
示例正常运行代码以使用上述内容:
public class Frame extends JFrame {
private static final long serialVersionUID = 1L;
private JProgressBar bar;
public Frame(){
JPanel contentPanel = (JPanel) getContentPane();
JButton b = new JButton("Do Process");
b.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
ProgressBarPainter p = new ProgressBarPainter();
p.jProgressBar1 = bar; //Fill in with the bar you want painted
Thread t = new Thread(p);
t.start();
Worker w = new Worker();
w.jProgressBar1 = bar;
Thread t2 = new Thread(w);
t2.start();
}
});
contentPanel.add(b, BorderLayout.SOUTH);
bar = new JProgressBar();
contentPanel.add(bar, BorderLayout.CENTER);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new Frame();
}
}
class Worker implements Runnable{
public JProgressBar jProgressBar1;
public void run(){
int x = 0;
while(jProgressBar1.getValue() != jProgressBar1.getMaximum()){
try {
//Do some work
Thread.sleep(50);
//Update bar
jProgressBar1.setValue(x++);
} catch (InterruptedException ex) {
break;
}
}
}
}
class ProgressBarPainter implements Runnable{
public JProgressBar jProgressBar1;
public void run(){
while(true){
try {
Thread.sleep(50);
jProgressBar1.repaint();
} catch (InterruptedException ex) {
break;
}
}
}
}