Как использовать JProgressBar?

Мне нужно загрузить набор слов (около 70 000) из текстового файла, добавить его в хеш-таблицу (используя soundex в качестве ключа) и отсортировать значения. Делая все это, я хочу показать индикатор выполнения, используя JProgressBar. Такие статьи, как эта и this дает только нереальный пример (цикл while). Может ли кто-нибудь предложить мне, как мне действовать. Как я могу получить число из приведенного выше условия, чтобы установить значение для индикатора выполнения? Также кажется, что есть разные способы сделать это - с помощью потока, таймера и т. д. Какой метод может быть лучшим для ситуации, такой как выше?


person javac    schedule 10.11.2008    source источник
comment
посмотрите этот простой пример для JProgressbar   -  person Digvijay Todkar    schedule 11.05.2012


Ответы (3)


Я бы читал текстовый файл в цикле в выделенном рабочем потоке, а не в потоке отправки событий (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()...)
person Zach Scrivena    schedule 10.11.2008
comment
Отличная работа Зак! Но мне интересно, не сделает ли это мою программу слишком медленной. Кажется, мне нужно дважды обработать входной файл - один раз, чтобы определить нет. слов и еще раз, чтобы обработать каждое слово. Есть ли у вас какие-либо предложения для этого? Например, хранить все слова в массиве или что-то в этом роде. - person javac; 10.11.2008
comment
Это зависит от того, где находится узкое место... Я полагаю, что чтение файла будет медленнее, чем вычисление представлений soundex и добавление их на карту. (продолжение...) - person Zach Scrivena; 10.11.2008
comment
(...продолжение) Если это так, я бы не стал читать файл дважды. Вместо этого я бы использовал длину файла в качестве общей суммы и количество обработанных символов в качестве подсчета (это, конечно, только приблизительное значение, поскольку длина файла указывается в байтах, а не в символах). - person Zach Scrivena; 10.11.2008
comment
@Zach: тогда используйте количество прочитанных байтов вместо количества символов. Видеть, как индикатор выполнения застревает на 100 (потому что вы переполняетесь, а связанная модель не позволит вам превысить 100) или не может достичь 100 после завершения задачи, это реально, это не было написано профессиональным запахом. - person Ran Biron; 10.11.2008
comment
@Ran: Вы подняли хороший вопрос! Предполагая, что каждый символ представлен как минимум одним байтом, обработка может быть завершена до того, как индикатор выполнения достигнет 100%. Как вы сказали, вместо этого мы можем подсчитать байты, но это потребует дополнительной работы (нельзя просто использовать простой FileReader). - person Zach Scrivena; 10.11.2008

Используйте SwingWorker: http://java.sun.com/docs/books/tutorial/uiswing/concurrency/interim.html

person yanchenko    schedule 20.02.2009

Получите размер файла и подсчитайте байты, обработанные на каждой итерации. Таким образом, вам не придется дважды просматривать файл.

person Sean Anderson    schedule 19.11.2010