简体   繁体   English

处理时更新 JProgressBar

[英]updating a JProgressBar while processing

I know the subject has already been seen on many Questions and has been answered, but still, I can't get trough it.我知道这个主题已经在许多问题上看到并得到了回答,但我仍然无法理解它。

I just want to update a progressBar while extracting some stuff of a large xml file.我只想在提取大型 xml 文件的一些内容更新进度条 I thought it was enough to have the time-consuming loop in a different thread but ?.. All I managed to get is the progressBar either not showed at all, or updated at the end, just before it's closed.我认为在不同的线程中进行耗时的循环就足够了,但是?.. 我设法得到的只是progressBar 要么根本没有显示,要么在结束时更新,就在它关闭之前。

Instanced somewhere near the launch of the application, I have:在应用程序启动附近的某个地方,我有:

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

while showing and updating a JDialog with a JProgressBar:使用 JProgressBar 显示和更新 JDialog 时:

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

So I have this myXMLParser :所以我有这个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;
    }
}

I have seen many things with SwingWorker and using PropertyChange events update the progressBar, but examples are always given all-in-one , with the processing and the progressbar within the same class, and with classes within classes, and since I begin in Java, I wasn't able to translate that to my situation.我在SwingWorker看到了很多事情,并且使用PropertyChange事件更新了进度条,但是示例总是一体式给出,处理和进度条在同一个类中,以及类中的类,自从我开始使用 Java,我无法将其转化为我的情况。

Any help ?.. Any (not too obvious) advices ?有什么帮助吗?.. 有什么(不太明显的)建议吗?

Edit: So thanks to btantlinger it worked like that:编辑:所以多亏了 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;
    }
}

You MUST update the JProgress bar on the Swing Event Dispatch Thread.您必须更新 Swing 事件调度线程上的 JProgress 栏。 You cannot modify Swing components on any other thread.您不能在任何其他线程上修改 Swing 组件。

Your only other alternative would be to set the JProgress bar "indeterminate" before you start your thread where the progress bar will just go back and forth.您唯一的其他选择是在开始您的线程之前将 JProgress 栏设置为“不确定”,其中进度栏只会来回移动。

Eg例如

progBar.setIndeterminate(true);

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

If you don't want to use the SwingWorker, another option is the SwingUtilities.invokeLater method如果您不想使用 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);


    }
});

In addition to the code provided by @btantlinger, I found after testing that it required an additional line of code in order to update the progress bar on the UI thread while processing.除了@btanlinger 提供的代码,我经过测试发现还需要额外的一行代码,以便在处理时更新UI线程上的进度条。 See below.见下文。

   SwingUtilities.invokeLater(new Runnable() {
       public void run() {
           progressBar.setValue((int)percentage);
           //below code to update progress bar while running on thread
           progressBar.update(progressBar.getGraphics());
       }
     });   

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM