来自SwingWorker的jProgressBar更新 [英] jProgressBar update from SwingWorker

查看:122
本文介绍了来自SwingWorker的jProgressBar更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用来通过更新ProgressBar来监视长时间运行的任务。
长时间运行的任务当然是在Swingworker线程中执行的。

I use to monitor a long running task by updating a ProgressBar. The long running task is of course performed in a Swingworker thread.

我曾经用这样的方式编程:

I used to program things like that :

public class MySwingWorkerClass extends SwingWorker<Void, Void> {   
    private JProgressBar progressBar;    

    public MySwingWorker(JProgressBar aProgressBar) {        
        this.progressBar = aProgressBar;           
        progressBar.setVisible(true);        
        progressBar.setStringPainted(true);
        progressBar.setValue(0);        
    }

    @Override
    public Void doInBackground() {
        //long running task
        loop {  
            calculation();
            progressBar.setValue(value);
        }
        return null;
    }    

    @Override
    public void done() {                
        progressBar.setValue(100);
        progressBar.setStringPainted(false);
        progressBar.setVisible(false);      
   }
}

但最近我发现我可以通过使用setProgress并定义属性更改并执行类似的操作

but recently I discovered that I could do it by using the "setProgress" and defining the property change and do things like that

public class MySwingWorkerClass extends SwingWorker<Void, Void> {   
    private JProgressBar progressBar;    

    public MySwingWorker(JProgressBar aProgressBar) {        
        addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                if ("progress".equals(evt.getPropertyName())) {
                    progressBar.setValue((Integer) evt.getNewValue());
                }
            }
        });

        progressBar.setVisible(true);        
        progressBar.setStringPainted(true);
        progressBar.setValue(0);
        setProgress(0);
    }

    @Override
    public Void doInBackground() {
        //long running task
        loop {  
            calculation();
            setProgress(value);
        }
        return null;
    }    

    @Override
    public void done() {                
        setProgress(100);
        progressBar.setValue(100);
        progressBar.setStringPainted(false);
        progressBar.setVisible(false);      
   }
}

我的问题是:我的第一个代码是可接受的还是应该是我使用setProgress进行任何调整吗?
我发现第二个代码更复杂,在我的情况下,不知道是否有任何优势或理由使用第二个。

My question is : is my first code acceptable or shall I use the setProgress for anyreason ? I find the second code more complicated and in my case and don't know if there is any advantage or reason to use the second one.

任何建议?

编辑
感谢您的回答。作为总结。
第一个解决方案是错误的,因为进度条更新是在EDT之外执行的。
第二个解决方案是正确的,因为进度条更新是在EDT内执行的

EDIT Thanks for the answer. As a summary. First solution is "wrong" because of the progress bar update is performed outside the EDT. Second solution is "correct" because the progress bar update is performed inside the EDT

现在,根据我案例中@mKorbel的有趣答案我的计算给出了我插入的HTML文本结果(参见此链接 )。我目前的代码如下。

Now, according to the "interesting" answer of @mKorbel in my case my calculation give results in HTML text which I "insert" (see this link). My current code is the following.

我发布(字符串),我的流程代码看起来像那样

I publish(string) and my process code looks like that

@Override
    protected void process(List<String> strings) {
        for (String s : strings) {
            try {
                htmlDoc.insertBeforeEnd(htmlDoc.getElement(htmlDoc.getDefaultRootElement(), StyleConstants.NameAttribute, HTML.Tag.TABLE), s);
            } catch (BadLocationException ex) {
            } catch (IOException ex) {
            }
        }
    }

在我的情况下,我如何重复使用@mKobel来做同样的事情。我的意思是他在我的情况下使用覆盖表格渲染我应该覆盖什么渲染器(jTextPane?)以及如何?

How can I reuse @mKobel to do the same in my case. I mean he use to override table rendering in my case what renderer shall I override (jTextPane?) and how ?

推荐答案

在第一个代码,您在非EDT(事件调度程序线程)线程中调用以下行。所以它不是线程安全的:

In the first code, you are calling the following line in a non-EDT (Event Dispatcher Thread) thread. So it is not thread safe:

progressBar.setValue(value);

由于Swing不是设计为线程安全库,因此可能会导致意外行为。

This may result in unexpected behaviour as Swing is not designed as a thread-safe library.

有不同的方法可以在Swing方式中执行此操作。一个正确的方法就是你在第二篇文章中所做的。另一种方法是使用 publish()/ process()方法,第三种方法是编写自己的线程而不是 SwingWorker 并使用 SwingUtilities.invokeLater()

There are different methods to perform this in the Swing way. One correct way of this is what you have done in the second post. Another would be to use publish()/process() methods, and a third method would be writing your own thread instead of SwingWorker and using SwingUtilities.invokeLater().

这篇关于来自SwingWorker的jProgressBar更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆