JDialog 小程序在 Mac OSX 中未正确隐藏

发布于 2024-08-11 04:17:54 字数 1590 浏览 1 评论 0原文

我有一个小程序,它调用包含 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() 业务逻辑包装在单独的新线程中似乎可行,但将实际业务逻辑代码重构到单独的线程中并不容易,所以我希望有一个更简单的解决方案。

环境是: Mac OS X 10.5 爪哇1.5 火狐2/3/3.5

I have an applet that calls a JDialog that contains a JProgressBar component. I subclass the JDialog to expose a method to update the JProgressBar, something like:

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

I use this dialog in the following manner:

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

It works fine on Windows/any browser. However, when invoking the above function on Firefox 2/3/3.5 on a Mac, the progressDialog is displayed indefinitely, i.e. it doesn't close.

I suspected that calling setVisible(true) inside the EventQueue was causing the problem, since it's a blocking call and might block the queue completely, so I tried changing it to:

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

With this change, the progressDialog now closes correctly, but a new problem emerged - the contents of the dialog (which included the progressbar, an icon and a JLabel used to show a message string) were no longer shown inside the dialog. It was still a problem only on Mac Firefox.

Any ideas? I realize it's probably some AWT threading issue, but I've been at this for a couple of days and can't find a good solution. Wrapping the doStuff() business logic in a separate new Thread seems to work, but it's not easy to refactor the actual business logic code into a separate thread, so I'm hoping there's a simpler solution.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

零度℉ 2024-08-18 04:17:54

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

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

Found out that the problem was that the applet function was executing inside the AWT dispatcher thread, therefore the thread blocks and no events are processed until the applet function finishes execution.

Solution was to move the processing logic into a separate thread spawned by the ProgressDialog object before calling setVisible(true). setVisible(true) would block the main thread but still allow the event dispatcher to continue processing, hence rendering the contents of the dialog until the spawned thread calls setVisible(false) to hide the dialog.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文