簡體   English   中英

處理時更新 JProgressBar

[英]updating a JProgressBar while processing

我知道這個主題已經在許多問題上看到並得到了回答,但我仍然無法理解它。

我只想在提取大型 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事件更新了進度條,但是示例總是一體式給出,處理和進度條在同一個類中,以及類中的類,自從我開始使用 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);


    }
});

除了@btanlinger 提供的代碼,我經過測試發現還需要額外的一行代碼,以便在處理時更新UI線程上的進度條。 見下文。

   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