Немодальный JDialog не показывает содержимое - PullRequest
3 голосов
/ 19 марта 2011

(Java SE 6) Я пытаюсь создать всплывающее диалоговое окно, которое отображает сообщение «Пожалуйста, подождите», пока моя программа выполняет некоторую трудоемкую работу.Для этого я решил использовать немодальный JDialog, чтобы программа продолжала работать и работала, пока JDialog виден (если вы используете модальный режим, программа остановится, пока пользователь не закроет диалоговое окно).

Проблема в том, что когда вы используете немодальное диалоговое окно таким образом, появляется JDialog с заголовком, а содержимое - нет (полагаю, по какой-то причине они не окрашиваются).Я пытался вызвать перерисовку и т. Д., Но, похоже, ничего не работает.

Теперь, по словам группы людей, которые находятся в паутинах, это подлинная ошибка в Swing, и единственные ответы, которые я нашел, это не делатьтак и найдите другие способы уведомления пользователя о необходимости ждать.Мне любопытно, если у кого-то здесь была эта проблема прежде, и нашел обходной путь.

Спасибо!

Ответы [ 4 ]

5 голосов
/ 13 декабря 2012

Это не ошибка, вы должны выполнить свою тяжелую работу и свою легкую работу качания в отдельной нити рядом с основной нитью.Это необходимо из-за логических наложений между потоком графического интерфейса 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 и панель содержимого Балька, но ...

Следующая попытка:

//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();
    // ... 
    }
//...
}

и наконец это сработало, надеюсь, это поможет;)

4 голосов
/ 19 марта 2011

В качестве альтернативы рассмотрите возможность использования SwingWorker и показа промежуточного прогресса, как предложено в этом примере .

2 голосов
/ 29 мая 2011

Я использую это, и оно работает - исходный код (без исправления, которое я нашел для перерисовки во время работы), отсюда: 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());

Потребовалось много времени, проб и ошибок, чтобы найти это решение. Надеюсь, что это работает для вас, как и для меня.

0 голосов
/ 19 марта 2011

Вы пробовали validate () (это необходимо после добавления компонентов в контейнер)? Также рассмотрите возможность размещения исходного кода, чтобы мы могли проверить его. Удачи.

...