在处理时更新JProgressBar

use*_*548 4 java swing swingworker jprogressbar event-dispatch-thread

我知道这个问题已经在许多问题上被看到并且已经得到了回答,但是,我仍然无法理解它.

我只想在提取大型xml文件的某些内容更新progressBar.我认为在不同的线程中使用耗时的循环已经足够了但是?所有我设法获得的是progressBar要么根本没有显示,要么在结束之前更新,就在它关闭之前.

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

public class SomeClass {
    private SomeClass () {
        myXMLParser reader = new myXMLParser();
        CoolStuff fromXml = reader.readTheXml();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用JProgressBar显示和更新JDialog时:

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

所以我有这个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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经看到很多事情SwingWorker和使用PropertyChange事件更新progressBar,但是示例总是一一给出,处理和进度条在同一个类中,并且在类中有类,并且因为我从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;
    }
}
Run Code Online (Sandbox Code Playgroud)

bta*_*ger 10

你必须更新Swing Event Dispatch Thread上的JProgress栏.您无法在任何其他线程上修改Swing组件.

你唯一的另一种选择是在开始你的线程之前将JProgress栏设置为"indeterminate",其中进度条将来回转换.

例如

progBar.setIndeterminate(true);
Run Code Online (Sandbox Code Playgroud)

请参阅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);


    }
});
Run Code Online (Sandbox Code Playgroud)