java - 在处理时更新 JProgressBar

标签 java swing swingworker jprogressbar event-dispatch-thread

我知道这个主题已经在很多问题上看到并得到了回答,但我仍然无法理解它。

我只想在提取大型 xml 文件的一些内容时更新进度条。 我认为在不同的线程中进行耗时循环就足够了,但是?.. 我设法得到的只是 progressBar 要么根本不显示,要么在结束时更新,就在它关闭之前。

在应用程序启动附近的某处实例化,我有:

public class SomeClass {
    private SomeClass () {
        myXMLParser reader = new myXMLParser();
        CoolStuff fromXml = reader.readTheXml();
    }
}

用 JProgressBar 显示和更新 JDialog 时:

public class LoadingDialog extends JDialog {
    private JProgressBar progressBar;
    /* ... */
    public void progress() {
        progressBar.setValue(progressBar.getValue() + 1);
    }
}

所以我有这个myXMLParser:

public class myXMLParser {
    private LoadingDialog loadingDialog = new LoadingDialog();

    public CoolStuff readTheXml() {
        CoolStuff fromXml = new CoolStuff();
        while(manyIterations) {
            loadingDialog.progress();
            fromXml.add(some() + xml() + reading());
        }
        return fromXml;
    }
}

我已经看到很多关于 SwingWorker 和使用 PropertyChange 事件更新 progressBar 的事情,但是总是给出示例 all-in-one,在同一个类中使用处理和进度条,在类中使用类,并且由于我是从 Java 开始的,所以我无法将其转换为我的情况。

有什么帮助吗?.. 有什么(不太明显的)建议吗?

编辑:感谢 btantlinger,它的工作方式如下:

public class SomeClass {
    private SomeClass () {
        myXMLParser reader = new myXMLParser();
        new Thread(new Runnable() {
            @Override
            public void run() {
                CoolStuff fromXml = reader.readTheXml();
            }
        }).start();
    }
}

public class LoadingDialog extends JDialog {
    private JProgressBar progressBar;
    /* ... */
    public void progress() {
        progressBar.setValue(progressBar.getValue() + 1);
    }
}

public class myXMLParser {
    private LoadingDialog loadingDialog = new LoadingDialog();

    public CoolStuff readTheXml() {
        CoolStuff fromXml = new CoolStuff();
        while(manyIterations) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    loadingDialog.progress();
                }
            });
            fromXml.add(some() + xml() + reading());
        }
        return fromXml;
    }
}

最佳答案

您必须更新 Swing 事件调度线程上的 JProgress 栏。您不能在任何其他线程上修改 Swing 组件。

您唯一的其他选择是在您开始您的线程之前将 JProgress 栏设置为“不确定”,进度条将来回移动。

例如

progBar.setIndeterminate(true);

请参阅 SwingWorker javadoc: http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html

如果您不想使用 SwingWorker,另一种选择是 SwingUtilities.invokeLater 方法

//inside your long running thread when you want to update a Swing component
SwingUtilities.invokeLater(new Runnable() {
    public void run() {

        //This will be called on the EDT
        progressBar.setValue(progressBar.getValue() + 1);


    }
});

关于java - 在处理时更新 JProgressBar,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9578694/

相关文章:

JAVA:哈希码:是否有可能多个元素具有相同的哈希码?

java - 如何将 Stream<List<Long>> flatMapToLong?

java - 事件派发线程在哪里调用?

java - java swing 文档中 Position 实例的处理

java - SwingWorker 在完成工作后设置标志

java - 用于快速排序的 Fork/Join 框架比普通快速排序执行时间更长

java - 正则表达式:多次提取条目

java - 删除整个 JTable

java - 在我自己的项目中使用 Java 源代码

java - 如何使用SwingWorker实时更新GUI?