JDialog的Applet在Mac OSX中无法正确隐藏

时间:2009-11-18 06:58:03

标签: java macos applet

我有一个applet,它调用包含JProgressBar组件的JDialog。我将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 /任何浏览器。但是,在Mac上的Firefox 2/3 / 3.5上调用上述功能时,progressDialog会无限期显示,即它不会关闭。

我怀疑在EventQueue中调用setVisible(true)导致了问题,因为它是一个阻塞调用并且可能完全阻塞队列,所以我尝试将其更改为:

        // 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 个答案:

答案 0 :(得分:1)

发现问题是applet函数在AWT调度程序线程内执行,因此线程阻塞并且在applet函数完成执行之前不会处理任何事件。

解决方法是在调用setVisible(true)之前将处理逻辑移动到由ProgressDialog对象生成的单独线程中。 setVisible(true)会阻塞主线程,但仍然允许事件调度程序继续处理,从而呈现对话框的内容,直到生成的线程调用setVisible(false)来隐藏对话框。