如何使用JProgressBar?

7
我需要从文本文件中加载大约70,000个单词,将其添加到哈希表中(使用soundex作为键),并对值进行排序。在执行所有这些操作时,我想使用JProgressBar显示进度条。像这个这个这样的文章只提供了一个非实际的例子(一个while循环)。有人能建议我该如何继续吗?如何从上述条件中获取数字以设置进度条的值?此外,似乎有不同的方法可以做到这一点 - 使用线程、计时器等。哪种方法对于上述情况可能是最好的?

请查看这个JProgressbar的简单示例 - Digvijay Todkar
3个回答

7
我建议您在一个专用的工作线程上循环读取文本文件,而不是事件分派线程(EDT)。如果我知道要读取的单词总数,则可以在循环的每个迭代中计算已完成的百分比,并相应地更新进度条。
以下代码在预处理和后处理期间将进度条置于不确定模式,并显示指示正在进行工作的动画。当从输入文件进行迭代读取时,使用确定模式。 示例代码
// INITIALIZATION ON EDT 

// JProgressBar progress = new JProgressBar();
// progress.setStringPainted(true);

// PREPROCESSING

// update progress bar (indeterminate mode)
SwingUtilities.invokeLater(new Runnable()
{
    @Override
    public void run()
    {
        progress.setIndeterminate(true);
        progress.setString("Preprocessing...");
    }
});

// perform preprocessing (open input file, determine total number of words, etc)

// PROCESSING 

// update progress bar (switch to determinate mode)
SwingUtilities.invokeLater(new Runnable()
{
    @Override
    public void run()
    {
        progress.setIndeterminate(false);
    }
});

int count = 0;

while (true)
{
    // read a word from the input file; exit loop if EOF

    // compute soundex representation

    // add entry to map (hash table)

    // compute percentage completed
    count++;
    final int percent = count * 100 / total;

    // update progress bar on the EDT
    SwingUtilities.invokeLater(new Runnable()
    {
        @Override
        public void run()
        {
            progress.setString("Processing " + percent + "%");
            progress.setValue(percent);
        }
    });
}

// POSTPROCESSING 

// update progress bar (switch to indeterminate mode)
SwingUtilities.invokeLater(new Runnable()
{
    @Override
    public void run()
    {
        progress.setIndeterminate(true);
        progress.setString("Postprocessing...");
    }
});

// perform postprocessing (close input file, etc)

// DONE! 

SwingUtilities.invokeLater(new Runnable()
{
    @Override
    public void run()
    {
        progress.setIndeterminate(false);
        progress.setString("Done!");
        progress.setValue(100);
    }
});

建议

  • 考虑编写一个方便的方法来在EDT上更新进度条,以减少代码中的混乱 (SwingUtilities.invokeLater... public void run()...)

干得好,Zach!但我想知道这是否会使我的程序变得太慢。看起来我需要两次处理输入文件——一次确定单词数量,另一次处理每个单词。你有什么建议吗?比如将所有单词保存在数组中或类似的东西。 - javac
这取决于瓶颈在哪里...我想读取文件的速度会比计算soundex表示并将它们添加到映射中要慢。(续...) - Zach Scrivena
如果是这样,我就不想两次读取文件。相反,我会使用文件长度作为“总数”,使用处理的字符数作为“计数”(当然,这只是一个近似值,因为文件长度以字节而非字符给出)。 - Zach Scrivena
@Zach:那就使用已读取的字节数,而不是字符数。看到进度条停在100上(因为溢出和绑定模型不允许你超过100),或在任务结束后未能达到100,这是真正的“没被专业人士编写”的味道。 - Ran Biron
@Ran:你提出了一个很好的观点!假设每个字符至少由一个字节表示,处理可能会在进度条达到100%之前完成。正如你所说,我们可以计算字节,但这需要更多的工作(不能只使用简单的FileReader)。 - Zach Scrivena


0

获取文件大小并计算每次迭代处理的字节数。这样,您就不必两次循环遍历文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接