【问题标题】:java update progressbarjava更新进度条
【发布时间】:2011-06-06 17:20:27
【问题描述】:

我有一个 JFrame 和以下组件。

JButton = jButton1 Progress Bar = progressBar 及其公共静态 JLabel = 状态及其公共静态

当点击按钮时,会执行不同的语句。我想在每个语句之后更新我的进度条。这是我的代码

   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;
    }

}

知道如何解决这个问题吗?

【问题讨论】:

    标签: java swing


    【解决方案1】:
       @Override
        protected Object doInBackground() throws Exception {
            NewJFrame1.progressBar.setValue(progress);
            NewJFrame1.status.setValue(stat);
            return null;
        }
    

    您不想从 Swing 线程更新 GUI 组件。 SwingWorker 提供了在 Event Dispatch Thread 上做事的钩子,这就是它的设计目的。从doInBackground 调用publish 方法并覆盖process 以使用增量更新详细说明。或者,如果您只需要在完成后更新 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);
        }
    }
    

    编辑

    @mKorbel 提出了一个很好的观点,即要使上述内容正常工作,它需要扩展 SwingWorker&lt;Void, Integer&gt;...Void 作为整体返回值类型(在这种情况下表示没有返回值)并且 Integer 是增量更新的类型。

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

    【讨论】:

    • 请修改您的答案,并添加(这不是真正的 OP 问题) SwingWorker 必须声明为 SwingWorker 而不是普通的 OP 声明的“公共类任务扩展 SwingWorker{..}”
    • @mKorbel 提出了一个很好的观点。 SwingWorker 的通用参数非常值得努力。有相关的例子here和API本身。
    • @mKorbel, @trashgod:谢谢我已经更新了我的答案,现在明确地说出来。
    • 另外关于@trashgod 的链接,它显示了在其值为0-100 的特殊情况下专门执行进度条的更直接的方法。因此,我的示例有点做作,因为明确支持基于百分比的进度更新。
    【解决方案2】:

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

    在 SwingWorker 或其他线程中等待。

    【讨论】:

    • +1 完全正确;这个example 在后台线程中休眠以模拟延迟。
    猜你喜欢
    • 2015-08-11
    • 2013-03-08
    • 2020-11-05
    • 2014-04-09
    • 1970-01-01
    • 2013-06-10
    • 2018-11-02
    • 1970-01-01
    相关资源
    最近更新 更多