Java ProgressMonitor не работает
Мой код, как показано ниже, не работает, может кто-нибудь сказать мне, почему? Пожалуйста, исправьте мой код, я новичок в Java. Кроме того, я ищу "компонент панели загрузки", что-то вроде ProgressMonitor
но может быть более привлекательным, и который оживляет лучше. Пожалуйста, предложите мне, если кто-то использовал такие вещи раньше.
public class Main extends JFrame {
private JPanel contentPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
ProgressMonitor pm = new ProgressMonitor(frame, "Loading...",
"waiting...",
0, 100000);
for (int i = 0 ; i < 100000 ; i ++){
pm.setProgress(i);
pm.setNote("Testing");
System.out.println(i);
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
}
}
3 ответа
Как уже отмечалось @Mark Rotteveel, вы удерживаете EDT (Thread Dispatch Thread) занятым. Учебное пособие "Как отображать индикаторы выполнения / мониторы" содержит ценную информацию и примеры кода.
Но в основном все сводится к переносу ваших вычислений в рабочий поток (например, с использованием SwingWorker
) и показывая ProgressMonitor
на EDT. Это до рабочего потока, чтобы указать ProgressMonitor
какой прогресс уже достигнут.
А вот прямая ссылка на пример кода этого учебника, который ясно показывает, как работа выполняется в SwingWorker
расширение (Task
класс в этом примере), и как ProgressMonitor
обновляется путем добавления PropertyChangeListener
к SwingWorker
где слушатель передает прогресс в ProgressMonitor
,
Я также предложил бы прочитать учебник Concurrency in Swing, который содержит больше информации о том, как обращаться Thread
s в сочетании с Swing, и почему вы не можете / не должны делать тяжелые вычисления на EDT
В Swing поток событий - это то, что изменяет и обновляет графический интерфейс. Поток событий занят этим циклом for и sleep, поэтому он не может обновить GUI. Все, что вы делаете в потоке событий, должно быть недолгим. Все остальное должно быть удалено из потока событий.
Так что вам нужно переместить этот цикл for из потока событий.
1. Считайте это эмпирическим правилом: пользовательский интерфейс работает в потоке пользовательского интерфейса, а не-пользовательский интерфейс - в не-пользовательском потоке.
2. Поток диспетчера событий (EDT) - это поток пользовательского интерфейса, поэтому вы должны поддерживать интенсивную работу, не связанную с пользовательским интерфейсом, в отдельном потоке вне EDT.
3. Вы можете сделать это двумя способами.....
я. Создайте отдельную тему для этого.
II. Используйте SwingWorker для синхронизации не-пользовательского интерфейса и потока пользовательского интерфейса.
4. Всегда оставляйте метод main() только для того, чтобы JFrame был виден в EDT.
например:
public static void main(String[] args){
EventQueue.invokeLater(new Runnable(){
public void run(){
myframe.setVisible(true);
}
}
}
Посмотрите на этот сайт рабочий пример SwingWorker: