簡體   English   中英

在過程完成之前,JProgressBar不會更新

[英]JProgressBar will not update until process is completed

我知道這里有很多JProgressBar問題,但是通過所有答案,我似乎無法診斷出我的問題。 我正在使用某些地址驗證軟件來處理文件。 我單擊“處理”按鈕,我需要我的JProgressBar來更新每個處理的文件。 這是按鈕:

private JButton getJButton0() {
...
   jButton0.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
         jButton0ActionActionPerformed(event);
         t.start();
      }
...

根據每個人的建議,我在線程中使用了setValue()方法

Thread t = new Thread(){
    public void run() {
    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        jProgressBar0.setValue(BulkProcessor.getPercentComplete());
    }
});
try {
    Thread.sleep(100);
} catch (InterruptedException e) {
}
...

BulkProcessor.getPercentComplete()是我從另一個類(表示完成百分比)中調用的方法。 我已經測試了這種方法,它可以正確更新。 問題在於,進度條在文件完成處理之前不會更新,然后它將跳到100%。 如果這是一個重復的問題,我深表歉意,但是我在這個網站上做了大量認真的研究,沒有運氣。 任何幫助,不勝感激。

編輯:

對於推薦的重復項,我嘗試了以下操作:

public void update(){
   new SwingWorker<Void,Void>() {
   protected Void doInBackground() throws Exception {
   jProgressBar0.setValue(BulkProcessor.getPercentComplete());
   return null;
 };
 }.execute();
}

然后嘗試在actionPerformed()下調用此update()方法(將t.start()update()切換)。 我仍然有同樣的問題。

編輯

根據user1676075的建議,但是存在相同的問題:

    public static void update(){
       new SwingWorker<Void,Integer>() {
       protected Void doInBackground() throws Exception {
           do
           {
           percentComplete = BulkProcessor.getPercentComplete();
           publish(percentComplete);
           Thread.sleep(100);
           } while(percentComplete < 100);

        return null;
       }
       @Override
    protected
       void process(List<Integer> progress)
       {
           jProgressBar0.setValue(progress.get(0));
       }
     }.execute();
   }

編輯

這是我的BulkProcessor類中的代碼

 private String getOutputLine( String searchString, String inputLine )
throws QasException
{
 ..(code for processing lines)..
 countRecord++;
    percentComplete = (int) Math.round((countRecord/totalRecord)*100);

totalRecord在主類我的更新BulkProcessor

 public static void main( String input, String output ){
    count.clear();
    try{
        String inputFile = input;
        String outputFile = output;
        LineNumberReader  lnr = new LineNumberReader(new FileReader(new File(input)));
        lnr.skip(Long.MAX_VALUE);
        totalRecord = lnr.getLineNumber() + 1; //line count in file
        BulkProcessor bulk = new BulkProcessor(inputFile, outputFile, ConfigManager.DFLT_NAME);
        bulk.process();
    }catch(Exception e ){
        e.printStackTrace();
    }

}

看起來您正在混合使用。 請參見頂部的SwingWorker文檔示例: http : //docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html

理想情況下,您可以在SwingWorker的doInBackground方法中更新BulkProcessor,這將調用setProgress,並且jProgressBar將像示例中那樣監聽這些進度更新。

如果這對您不起作用,似乎不僅僅是基於上述情況,請從按鈕按下事件中啟動SwingWorker。 像下面這樣實現SwingWorker方法(偽代碼):

new SwingWorker<Void,Integer>()
{
  doInBackground()
  {
    do
    {
      percentComplete = BulkProcessor.getPercentComplete();
      publish(percentCompete);
      Thread.sleep(100);
    } while (percentComplete < 100);
  }

  @Override
  process(List<Integer> progress)
  {
     jProgressBar0.setValue(progress.get(0));
  }
}.execute();

您需要添加錯誤處理並檢查完整案例和失敗案例,但這應該可以使您入門並達到您想要的目標。 doInBackground在后台線程中運行,因此不會阻止任何操作,而process()在swing worker線程上運行,因此將發布更新。

您可能繼續發生的錯誤是調用t.start();。 jButton0ActionPerformed(event); 這使得在執行操作之后線程將啟動。 因此,進度條的值未按預期更新。

您需要在jButton0ActionPerformed(event)中啟動線程; 然后更新其中的值。

只是預感,但是...

    percentComplete = (int) Math.round((countRecord/totalRecord)*100);

您確定這不是整數運算嗎? 我不知道totalRecord的類型,所以我不能肯定地說。

我猜一切都正常,只是進度一直都是0,直到完成神奇的100為止。這是因為一個整數除以一個整數不會得到分數值(即99/100 == 0, 100/100 == 1)。 這非常適合您遇到的症狀。

嘗試將上面的行替換為:

   percentComplete = (int) Math.round((countRecord/(double) totalRecord)*100);

看到它我是對的。 :-)

您是否嘗試過使用PropertyChangeListener -interface?

計算將由Swingworker線程完成,並且main-gui將實現此接口。 一些示例代碼

@Override
public void actionPerformed(ActionEvent e) {
    this.myButton.setEnabled(false);
    MyWorkerThread thread = new MyWorkerThread(); //Data-processing
    thread.addPropertyChangeListener(this.mainguiframe); //Separation of concern
    thread.execute();
}

使用swing-worker線程的“ setProgress”方法,如果發生某些情況,將通知main-gui線程。

@Override
public void propertyChange(PropertyChangeEvent property) {
     Integer currentValue = new Integer(0);
     currentValue = (Integer) property.getNewValue();
     this.progressBar.setValue(currentValue.intValue());
}

擺動不是線程安全的。 這不是最佳解決方案,但也許可以為您提供幫助。 如果有什么可怕的錯誤,請發表評論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM