Немодальный JDialog не показывает содержимое
(Java SE 6) Я пытаюсь создать всплывающее диалоговое окно, которое отображает сообщение "Пожалуйста, подождите", пока моя программа выполняет некоторую трудоемкую работу. Для этого я решил использовать немодальный JDialog, чтобы программа продолжала работать и работала, пока JDialog видим (если вы используете модальный режим, программа остановится, пока пользователь не закроет диалоговое окно),
Проблема в том, что когда вы используете немодальное диалоговое окно таким образом, появляется JDialog с заголовком, но содержимое не отображается (я думаю, по какой-то причине они не окрашиваются). Я пытался позвонить перекрасить и т. Д., Но ничего не получается.
Теперь, по словам группы людей, работающих в сети, это настоящая ошибка в Swing, и единственные ответы, которые я нашел, - это не поступать таким образом и находить какие-то другие способы уведомления пользователя о необходимости ждать. Мне любопытно, если у кого-то здесь была эта проблема прежде, и нашел обходной путь.
Спасибо!
4 ответа
В качестве альтернативы рассмотрите возможность использования SwingWorker
и показывая промежуточный прогресс, как предложено в этом примере.
Это не ошибка, вы должны выполнить свою тяжелую работу и свою легкую работу качания в отдельной нити рядом с основной нитью. Это необходимо из-за логических наложений между потоком графического интерфейса Dialog и отношением ActionListenerEvents к тяжелому заданию веса в фоновом режиме. Если вы не отделяете свою основную нить, то будет определяться ничья Swing из-за некоторых событий уведомления. У меня была та же проблема, я пытался отслеживать ход выполнения загрузки по FTP, который я запустил из JFrame, чтобы показать его в JDialog.
Сначала я попробовал:
//Activated by Upload Button
public void actionPerformed(ActionEvent e) {
if("Upload".equals(e.getActionCommand())){
// some Declarations
new Thread(){
public void run() {
/*Run JDialog with the Upload - ProgressBar*/
FileUploadProgressBar fileUploadProgressBar = new FileUploadProgressBar(localFile, remoteFile, ftpPersistence);
}
}.start();
/*Run the heavy weigth Job - the Upload*/
ftpPersistence.uploadFile(localFile, remoteFile);
// ...
}
//...
}
Но так я получаю JDialog FrameBorder и панель содержимого Balck, но...
Следующая попытка:
//Activated by Upload Button
public void actionPerformed(ActionEvent e) {
if("Upload".equals(e.getActionCommand())){
// some Declarations
new Thread(){
public void run() {
/*Run JDialog with the Upload - ProgressBar*/
FileUploadProgressBar fileUploadProgressBar = new FileUploadProgressBar(localFile, remoteFile, ftpPersistence);
}
}.start();
new Thread(){
public void run()
/*Run the heavy weigth Job - the Upload*/
ftpPersistence.uploadFile(localFile, remoteFile);
}
}.start();
// ...
}
//...
}
и наконец это сработало, надеюсь, это поможет;)
Я использую это, и это работает - оригинальный код (без исправления, которое я нашел для перерисовки во время работы) находится здесь: http://inversionconsulting.blogspot.com/2008/03/java-jdialog-and-jprogressbar-example.html
но я объединил это (с небольшими изменениями):
JProgressBar pb = new JProgressBar(0,100);
pb.setPreferredSize(new Dimension(275,30));
pb.setString("Running");
pb.setStringPainted(true);
pb.setValue(0);
JLabel label = new JLabel("Progress: ");
JPanel center_panel = new JPanel();
center_panel.add(label);
center_panel.add(pb);
JDialog dialog = new JDialog((JFrame)null, "Working ...");
dialog.getContentPane().add(center_panel, BorderLayout.CENTER);
dialog.pack();
dialog.setVisible(true);
dialog.setLocationRelativeTo(null); // center on screen
Позже в моем коде, когда он выполняется через мой цикл (будучи от 1 до 10 с использованием переменной 'tot'), я перекрашиваю диалоговое окно, обновляя индикатор выполнения по мере того, как программа проходит цикл, таким образом (это не указано в ссылка на страницу выше) (я не использую несколько потоков, все это в основной теме):
//set progress bar
pb.setValue(tot*10);
//repaint it
dialog.getContentPane().paintAll(pb.getGraphics());
Чтобы найти это решение, потребовалось много времени, проб и ошибок. Надеюсь, что это работает для вас, как и для меня.
Вы пробовали validate () (это необходимо после добавления компонентов в контейнер)? Также рассмотрите возможность размещения исходного кода, чтобы мы могли проверить его. Удачи.