这是一项家庭作业,我要读取文件并根据用户选择的内容将所有字符转换为大写或小写。我已经完成了所有这些工作,但我不确定我的进度条是否会随着每个字符写入而更新,或者当文件写入完成时是否会跳到 100%。我的逻辑是在写入每个字符后,我增加一个计数器,然后在该增量之后我所以 progressBar.setValue(100 * (symbolsWritten/totalSymbols));
这是我的代码的一部分,用于检查字符是否存在是小写字母,如果需要的话将其转换为大写字母。我只是在学习,所以请不要太严厉地批评我的代码:) 谢谢您的评论。
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
最佳答案
这里发生了两件事。第一个是整数除法,因为 symbolsWritten
和 totalSymbols
都是 int。所以你永远不会从 int/int
得到小数值。它只会从 0 跳到 1。如果需要,您可以进行强制转换:
bar.setValue((int)Math.round(
100.0 * ((double)symbolsWritten / (double)totalSymbols)
));
(要么首先将它们定义为 double。如果值在 int 范围内,则可以在 double 上使用 ++
。)
另一种是更新值的方式,因为它应该在 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 会吃掉它们,但会抛出 ExecutionException 并带有如果您调用 get
,则吃掉异常作为其原因。)
如果您已经在 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有关发布的教程。
关于java - JProgressBar 可以通过简单地增加 setValue 来更新吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21792203/