只需增加setValue即可更新JProgressBar吗?

时间:2014-02-15 01:17:41

标签: 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

1 个答案:

答案 0 :(得分:2)

这里有两件事。第一个是整数除法,因为symbolsWrittentotalSymbols都是int。因此,您永远不会从int / int获得小数值。它只会从0跳到1.你可以根据需要进行演员表:

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

(或者将它们定义为双开始。如果值在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();
}

done中的有趣业务很奇怪但很重要,如果你想捕获在doInBackground中抛出的异常.SwingWorker会吃掉它们但会抛出ExecutionException,并将eaten异常作为其原因,如果你打电话给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