Java 更新JProgressBar

Java 更新JProgressBar,java,swing,multithreading,jprogressbar,runnable,Java,Swing,Multithreading,Jprogressbar,Runnable,我无法更新我的进度条。。。这是我的密码 Thread t=new Thread(new Runnable(){ public void run(){ int i=1; jProgBar.setMinimum(0); jProgBar.setMaximum(100); try { while(i<=100 || true){

我无法更新我的进度条。。。这是我的密码

Thread t=new Thread(new Runnable(){
        public void run(){
            int i=1;
            jProgBar.setMinimum(0);
            jProgBar.setMaximum(100);
            try {
                while(i<=100 || true){
                    jProgBar.setValue(i);
                    i++;
                    Thread.sleep(50);
                }
            }
            catch (InterruptedException ex){
                jProgBar.setValue(jProgBar.getMaximum());
            }
        }
    });
    t.start();

    .... Something code that correctly works

    t.interrupt();
Thread t=新线程(new Runnable(){
公开募捐{
int i=1;
jProgBar.setMinimum(0);
jProgBar.setMaximum(100);
试一试{

(i在睡眠之前,添加对SwingUtiles.invokeLater()的调用,该调用生成一个线程,在EDT的progressbar上触发firePropertyChange。

针对您的情况,最好的建议是使用SwingWorker。请在

重写过程方法以更新进度条的值(然后将在EDT上正确完成)


有关更多信息,请访问

直接使用模型而不是JProgressBar:

DefaultBoundedRangeModel model = new DefaultBoundedRangeModel();
JProgressBar bar = new JProgressBar(model);

// Somewhere else, perhaps in another Thread
model.setValue(i)
以下示例很好地工作:

public static void main(String[] args) throws InterruptedException {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(200, 100);
    frame.setVisible(true);
    final DefaultBoundedRangeModel model = new DefaultBoundedRangeModel();
    frame.add(new JProgressBar(model));
    Thread t = new Thread(new Runnable() {
        public void run() {
            int i = 1;
            model.setMinimum(0);
            model.setMaximum(100);
            try {
                while (i <= 100 || true) {
                    model.setValue(i);
                    i++;
                    Thread.sleep(50);
                }
            } catch (InterruptedException ex) {
                model.setValue(model.getMaximum());
            }
        }
    });
    t.start();

    Thread.sleep(2000);

    t.interrupt();
}
publicstaticvoidmain(String[]args)抛出InterruptedException{
JFrame=新JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
框架设置尺寸(200100);
frame.setVisible(true);
最终DefaultBoundedRangeModel模型=新DefaultBoundedRangeModel();
frame.add(新的JProgressBar(模型));
线程t=新线程(新的可运行线程(){
公开募捐{
int i=1;
model.setMinimum(0);
型号设定最大值(100);
试一试{

虽然(iPer eugener,
SwingWorker
绝对是您想要在这里使用的,或者任何时候生成一个长时间运行的任务,否则可能会在完成之前锁定您的GUI。有关使用进度条与
SwingWorker
的完整教程可从Sun^H^H^HOracle获得:

将此片段放入

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        jProgBar.repaint();
    }
}
在'i++'和'Thread.sleep()'之间应该可以完成这项工作。要编译它,请将jProgBar标记为'final'。

谢谢大家。 我就是这样解决的

try{
       jProgBar.setIndeterminate(true);
       jProgBar.setStringPainted(true);
       jProgBar.setBorderPainted(true);
       new Thread(new Runnable() {
           public void run() {
               ...
               // here is code that i've to wait
               // after this i stop my jProgressBar
               ...
               jProgBar.setStringPainted(false);
               jProgBar.setBorderPainted(true);
               jProgBar.setIndeterminate(false);
       }
       }).start();
   }
   catch(IllegalStateException ex){
       //some code
   }

是的,这是根据这样的原则,即对组件状态的任何更改都应该从事件分派线程完成。Swing显然是以这种方式设计的(单线程),以避免太多的复杂性。来自外部的任何调用都可能导致潜在的互锁。我的理解是invokeLater()将调用放在一种执行队列的末尾。是的,它可以工作。请参阅JDK1.6.0_20中的BasicProgressBarUI第1226-1229行,该行发出重新绘制()命令,生成Toolkit.getEventQueue().postEvent(e);