java - JProgressBar 可以通过简单地增加 setValue 来更新吗?

标签 java swing jprogressbar

这是一项家庭作业,我要读取文件并根据用户选择的内容将所有字符转换为大写或小写。我已经完成了所有这些工作,但我不确定我的进度条是否会随着每个字符写入而更新,或者当文件写入完成时是否会跳到 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

最佳答案

这里发生了两件事。第一个是整数除法,因为 symbolsWrittentotalSymbols 都是 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/

相关文章:

java - 错误 : Could not find or load main class . .. - Eclipse 之外的 Maven 项目

java - 我如何在java中处理Jcombobox的按键事件

java - 删除 JProgressBar 的不确定模式

java - 如何在不同的线程中使用 JProgressBar?

java - 如何使用Java API将配置单元字符串查询转换为抽象语法树?

java - 在运行时,获取传递给方法的参数/参数的数量,无论是否带有可变参数,在 Java 中

java - 如何在java中获取响应头

java - JTable 与 JScrollpane 中的 JPanel 列表

java - 为什么在添加两个面板时,分割 Pane 分隔线不会移动?

java - 如何显示处理信息。在程序中?