Как я могу завершить показ прогресса в JTextArea при выполнении кода, который определяет, что отображать в этой JTextArea?
Я не знаю, возможно ли это. Я делаю лотерею и пытаюсь использовать как можно меньше компонентов графического интерфейса. Итак, у меня есть JTextArea, который должен показывать следующее сообщение (например):
"Расчет...55,4%"
Когда я печатаю его на консоль, он показывает нормально, но не печатает его в JTextArea. Я пытался использовать SwingUtilities.invokeLater, но это тоже не работает.
for (int x = 0; x < daysBetween; x++)
{
completion = "Calculating..." + df.format((100 * (x + 1)) / daysBetween) + "%";
if (!textArea.getText().equals(completion))
{
textArea.setText(completion);
}
/*
Here I have a lot of irrelevant code that compares your tickets to the winning tickets and counts your winnings and other statistics...
*/
}
ticketReport += "Computation time: " + getElapsedTime(start, System.nanoTime());
ticketReport += "\nEnd date: " + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.DAY_OF_MONTH) + "/" + cal.get(Calendar.YEAR);
ticketReport += "\nTotal # of tickets purchased: " + numOfTicketsPurchased;
/*
etc. with filling out the ticket report
*/
textArea.setText(ticketReport);
Как вы можете догадаться, я хочу, чтобы JTextArea обновлялся, когда я устанавливал текст textArea в цикле for выше. Он не обновляет JTextArea до конца метода, который является самым нижним, когда я устанавливаю текстовую область для отображения отчета о тикете.
http://i63.tinypic.com/2s85j5t.png
МОЯ КОНЕЦНАЯ ЦЕЛЬ: Я хочу в конечном итоге превратить это в приложение для телефона Android, поэтому я не хочу использовать всплывающие окна или что-то еще.
2 ответа
Мой оригинальный подход к SwingWorker позволил мне показать процент выполнения в JTextArea. Я добавил опцию, чтобы отменить операцию, и когда я попытался отменить, "поток" (SwingWorker) не будет отменить. Когда я отменяю и перезапускаю, он будет постоянно складываться. Каждый последовательный запуск во время работы другого приводил к тому, что вычисления выполнялись все медленнее и медленнее, а затем давали неверную информацию.
То, как я это сделал во второй раз, решило исходную проблему и эту новую проблему. Я создал новый закрытый класс, который расширяет Thread, переопределяет его метод run() и вставил в этот код код, который будет выполняться в потоке. Я заметил, что любой метод остановки потока устарел из-за потенциальных проблем, поэтому я создал логическое значение, которое должно быть установлено, когда пользователь запрашивает остановку потока, и внутри потока оно периодически читает значение логического значения, а затем завершается, когда оно равно к истине.
Я запускаю поток путем повторной инициализации объекта BackgroundCalc и вызова его метода start().
private class BackgroundCalc extends Thread
{
public void run()
{
/*
initializing stuff here
*/
for (int x = 0; x < daysBetween; x++)
{
progress = (100 * (x + 1)) / daysBetween;
if (destroyCalcThread) return;
/*
background calculations here
*/
}
/*
finish up thread here
*/
}
}
Я немного неопытен с потоками, так что, надеюсь, моя борьба здесь и способ, которым я объяснил это, помогут кому-то еще, кто неопытен с концепцией.
/* РЕДАКТИРОВАТЬ: Это временно решило проблему, но я столкнулся с другой проблемой. Теперь, когда я попытался отменить SwingWorker, вызвав его метод cancel с параметром true, он не отменил. Пожалуйста, посмотрите мой другой ответ, как я решил это. */
Я понял. Вышеописанный метод, который я поместил внутрь SwingWorker, выглядит следующим образом:
SwingWorker<Void, Void> sw = new SwingWorker<Void, Void>()
{
@Override
protected Void doInBackground() throws Exception
{
//method here
}
}
Внутри этого метода я вызвал метод setProgress с параметром "(100 * (x + 1)) / daysBetween", чтобы показать правильный% выполнения. Затем после этого я добавил это:
sw.execute();
sw.addPropertyChangeListener(new PropertyChangeListener()
{
@Override
public void propertyChange(PropertyChangeEvent arg0)
{
textArea.setText("Calculating..." + sw.getProgress() + "%");
if (sw.getProgress() == 100)
textArea.setText(ticketReport);
}
});
Он показывает проценты в виде целых чисел, а не #.##, который я первоначально хотел, но я могу очень легко изменить, если бы захотел.