2014-02-15 31 views
1

這是一項家庭作業,我要讀取文件並根據用戶選擇的內容將所有字符轉換爲大寫或小寫。我已經掌握了所有這些工作,但是我不確定是否每個字符的寫入都會更新進度條,或者在文件寫入完成時跳至100%。我的邏輯是在每個字符被寫入之後,我增加一個計數器並且跟隨那個增量I如此progressBar.setValue(100 * (symbolsWritten/totalSymbols));這裏是我的代碼的一部分,它檢查一個字符是否爲小寫,如果需要將其轉換爲大寫。我只是在學習,所以請不要打我的代碼太糟糕:)謝謝你的意見。只需遞增setValue即可更新JProgressBar?

public void writeFileLC(char[] theCharArray) 
{ 
    int totalSymbols = theCharArray.length; 
    int symbolsWritten = 0; 
    int symbolsConverted = 0; 

    /*this loop checks to see if the character is upper case and converts 
    it if needed. Then it writes the characters to the output file via 
    the output object output*/ 
    for (int i = 0; i < theCharArray.length; i++) 
    { 
     if (Character.isUpperCase(theCharArray[i])) 
     { 
      try 
      { 
       output.format("%c", Character.toLowerCase(theCharArray[i])); 
       symbolsConverted++; 
       symbolsWritten++; 
       Symbols_converted_textfield.setText(String.valueOf(symbolsConverted)); 
       ProgressBar.setValue(100 * (symbolsWritten/totalSymbols)); 
      }//end try block 
      catch (FormatterClosedException formatterClosedException) 
      { 
       JOptionPane.showMessageDialog(this, "Error writing to file", 
         "Error writing to file", JOptionPane.ERROR_MESSAGE); 

      }//end catch 
     }//end if 

     else 
     { 
      try 
      { 
       output.format("%c", theCharArray[i]); 
       symbolsWritten++; 
       Symbols_converted_textfield.setText(String.valueOf(symbolsConverted)); 
       ProgressBar.setValue(100 * (symbolsWritten/totalSymbols)); 
      }//end try block 
      catch (FormatterClosedException formatterClosedException) 
      { 
       JOptionPane.showMessageDialog(this, "Error writing to file", 
         "Error writing to file", JOptionPane.ERROR_MESSAGE); 

      }//end catch 
     }//end else   
    }//end for 
}//end method writeFileLC 

回答

2

這裏有兩件事情要做。第一個是整數除法,因爲symbolsWrittentotalSymbols都是int。所以你永遠不會從int/int得到一個小數值。它只會從0跳到你可以選一投,如果你想:

bar.setValue((int)Math.round(
    100.0 * ((double)symbolsWritten/(double)totalSymbols) 
)); 

(無論是或將它們定義爲雙開始與它的確定上雙用++如果值是在一個int的範圍)

另一種是你更新值的方式,因爲它應該在the Event Dispatch Thread上完成。這取決於如何調用這個方法。如果在某個事件中調用此功能,則需要啓動一個background thread,否則在該過程完成之前不會顯示更新。

@Override 
public void actionPerformed(ActionEvent ae) { // some action event 
    final String someString = "SoMe StRiNg"; // some String 

    SwingWorker<Void, Void> task = new SwingWorker<Void, Void>() { 
     @Override 
     public Void doInBackground() { 
      writeFileLC(someString.toCharArray()); 
      return (Void)null; 
     } 
     @Override 
     public void done() { 
      try { 
       get(); 
      } catch(Exception e) { 
       e.printStackTrace(System.err); 
      } 
     } 
    }; 

    task.execute(); 
} 

(如果你想趕上那得到doInBackground拋出的異常的done有趣的業務是很奇怪,但很重要的。SwingWorker的會吃他們,但如果你打電話get將拋出ExecutionException當與食用例外,因爲它的原因。 )

如果您已經在SwingWorker或其他線程中運行此應用程序,則應該在EDT上調用這些更新。通過使用SwingWorker的publish或使用invokeLater

所以,當你想更新內部writeFileLC進度條:

final int progress = (int)Math.round(
    100.0 * ((double)symbolsWritten/(double)totalSymbols) 
); 

EventQueue.invokeLater(new Runnable() { 
    @Override 
    public void run() { 
     bar.setValue(progress); 
    } 
}); 

publish是少一點反應通常比invokeLater因爲它combines the results。就我個人而言,我通常使用invokeLater來更新進度條,但我認爲發佈是您「應該」這樣做的方式。

另請參閱Tasks that Have Interim Results的發佈教程。

+0

Radiodef感謝您的回答,但在這一點上它仍然超越了我。進度條對我來說是全新的,教師給了我們零信息,他們不在本週的閱讀中,所以我從頭開始。上面的代碼是從另一個按鈕按鈕調用的方法調用的,所以我認爲這在技術上是一個行爲事件?另外,當我決定使用int-int分區時,我認爲它會好的,因爲值會被截斷。對於進度條來說不好嗎?它不像它必須非常準確嗎? –

+0

我添加了一個SwingWorker示例(如果它可以幫助你的話)(你也可以使用一個普通的線程,它實際上可能會更容易)。只有在單獨的線程中運行任務時,更新進度條纔會完全不起作用。隨着部門,截斷適用於大數字,但你的總是一個介於0和1之間的分數。你可以嘗試'(100 * symbolsWritten)/ totalSymbols',我猜這會工作。 – Radiodef