Апплет с JDialog неправильно скрывается в Mac OSX - PullRequest
0 голосов
/ 18 ноября 2009

У меня есть апплет, который вызывает JDialog, который содержит компонент JProgressBar. Я делю JDialog на подклассы для предоставления метода для обновления JProgressBar, что-то вроде:

public class ProgressDialog extends javax.swing.JDialog {
    public void setProgress(double progress) {
        jProgressBar1.setValue(jProgressBar1.getMinimum() + (int) (progress * jProgressBar1.getMaximum()));
    }
    ...
}

Я использую этот диалог следующим образом:

public void test() throws Exception {
    progressDialog = new ProgressDialog(null, true);

    try {
        progressDialog.setLocationRelativeTo(null);

        // show the dialog
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                progressDialog.setVisible(true);
            }
        });

        // business logic code that calls progressDialog.setProgress along the way
        doStuff();

    } finally {
        progressDialog.setVisible(false);
        progressDialog.dispose();
    }
}

Отлично работает на Windows / любом браузере. Однако при вызове вышеупомянутой функции в Firefox 2/3 / 3.5 на Mac, progressDialog отображается бесконечно, то есть не закрывается.

Я подозревал, что вызов setVisible (true) внутри EventQueue вызывал проблему, так как это блокирующий вызов и может полностью заблокировать очередь, поэтому я попытался изменить его на:

        // show the dialog
        new Thread() {
            public void run() {
                progressDialog.setVisible(true);
            }
        }.start();

После этого изменения progressDialog теперь закрывается правильно, но возникла новая проблема - содержимое диалога (которое включало индикатор выполнения, значок и JLabel, используемый для отображения строки сообщения) больше не показывалось внутри диалога. Это все еще было проблемой только на Mac Firefox.

Есть идеи? Я понимаю, что это, вероятно, проблема с многопоточностью AWT, но я занимался этим пару дней и не могу найти хорошего решения. Кажется, что упаковка бизнес-логики doStuff () в отдельный новый поток работает, но реорганизовать фактический код бизнес-логики в отдельный поток непросто, поэтому я надеюсь, что есть более простое решение.

envt: Mac OSX 10.5 Java 1.5 Firefox 2/3 / 3.5

1 Ответ

1 голос
/ 19 ноября 2009

Обнаружено, что проблема заключалась в том, что функция апплета выполнялась внутри потока диспетчера AWT, поэтому блоки потока и никакие события не обрабатываются до тех пор, пока функция апплета не завершит выполнение.

Решением было переместить логику обработки в отдельный поток, созданный объектом ProgressDialog, перед вызовом setVisible (true). setVisible (true) блокирует основной поток, но все же позволяет диспетчеру событий продолжать обработку, следовательно, визуализируя содержимое диалога до тех пор, пока порожденный поток не вызовет setVisible (false), чтобы скрыть диалог.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...