代码之家  ›  专栏  ›  技术社区  ›  Roy Tang

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

  •  0
  • Roy Tang  · 技术社区  · 15 年前

    我有一个小程序,它调用包含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();
    

    有什么想法吗?我意识到这可能是AWT线程的问题,但我已经研究了几天,并没有找到一个好的解决方案。将doStuff()业务逻辑包装到一个单独的新线程中似乎是可行的,但是将实际的业务逻辑代码重构到一个单独的线程中并不容易,因此我希望有一个更简单的解决方案。

    MacOSX10.5 Java 1.5 Firefox 2/3/3.5

    1 回复  |  直到 15 年前
        1
  •  1
  •   Roy Tang    15 年前

    发现问题在于小程序函数在AWT dispatcher线程内执行,因此线程阻塞,在小程序函数完成执行之前不会处理任何事件。

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