java更新进度条

java更新进度条,java,swing,Java,Swing,我有一个JFrame和以下组件 JButton=jButton1 进度条=进度条及其公共静态 JLabel=状态及其公共静态 当按钮点击时,执行不同的语句。我想在每条语句之后更新progressbar。这是我的密码 private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { Task pbu = new Task

我有一个JFrame和以下组件

JButton=jButton1 进度条=进度条及其公共静态 JLabel=状态及其公共静态

当按钮点击时,执行不同的语句。我想在每条语句之后更新progressbar。这是我的密码

   private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        Task pbu = new Task(25, "Step 1....");
        pbu.execute();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

        pbu = new Task(50, "Step 2....");
        pbu.execute();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

        pbu = new Task(75, "Step 3....");
        pbu.execute();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }

        pbu = new Task(100, "Done");
        pbu.execute();
    }
这是我用SwingWorker扩展的任务类

public class Task extends SwingWorker{

    private int progress;
    private String stat;

    public Task(int pr, String st) {
        progress = pr;
        stat = st;
    }

    @Override
    protected Object doInBackground() throws Exception {
        NewJFrame1.progressBar.setValue(progress);
        NewJFrame1.status.setValue(stat);
        return null;
    }

}
你知道我该怎么解决这个问题吗

   @Override
    protected Object doInBackground() throws Exception {
        NewJFrame1.progressBar.setValue(progress);
        NewJFrame1.status.setValue(stat);
        return null;
    }
您不想在Swing线程之外更新GUI组件
SwingWorker
提供了钩子,用于在事件调度线程上执行操作,这就是它的设计目的。从
doInBackground
调用
publish
方法,并覆盖
过程
以增加更新细节。或者,如果您只需要在GUI完成时更新它,请重写
done()
方法

一个非常简单的例子:

//...in some concrete implementation of SwingWorker<Void, Integer>
protected Void doInBackground() throws Exception {
    //do 10% of task
    doLongOp();
    publish(10);

    //do another 20% of task
    doAnotherLongOp();
    publish(20);

    return null;
}

protected void process(List<Integer> pieces) {
    for (Integer percent : pieces ) {
       progressBar.setValue(progressBar.getValue() + percent);
    }
}
在SwingWorker的一些具体实现中 受保护的Void doInBackground()引发异常{ //完成10%的任务 doLongOp(); 出版(10); //再做20%的任务 doanotherlonglop(); 出版(20); 返回null; } 受保护的无效流程(列表件){ 用于(整数百分比:个数){ progressBar.setValue(progressBar.getValue()+百分比); } } 编辑 @mKorbel提出了一个很好的观点,即为了使上述方法发挥作用,它需要扩展
SwingWorker
Void
作为总体返回值类型(在本例中,表示没有返回值)和
Integer
作为增量更新的类型

如果工作程序生成实际的最终结果(将使用
get()
)检索),则可以使用该类型代替
Void
。因为我没有包含类声明,所以我省略了这些细节

看见

除了Mark的答案,您确实不想在
actionPerformed()
方法中睡觉。此方法(如果链接到GUI组件)由AWT/Swing事件调度线程调用,该线程也执行绘制和所有操作。只要您的方法没有完成,您的GUI就会被阻止


请在SwingWorker或其他线程中等待。

请修改您的答案,并添加(这不是OP的问题)SwingWorker必须声明为SwingWorker而不是普通的SwingWorker。OP声明的“公共类任务扩展SwingWorker{..}”@mKorbel的观点很好。要使用的通用参数非常值得付出努力。API本身也有相关的例子。@mKorbel,@trashgood:谢谢,我现在更新了我的答案,明确地说了这一点。另外关于@trashgood的链接,这显示了一种更直接的方法,可以在值为0-100的特殊情况下,专门制作进度条。因此,我的示例有点做作,因为它明确支持基于百分比的进度更新;这将在后台线程中休眠以模拟延迟。