在模块还原期间显示对话框会导致java.lang.IllegalStateException:没有可用的启动画面

时间:2017-09-29 14:31:55

标签: rcp netbeans-platform

我的应用程序建立在Netbeans平台之上,我需要在加载其中一个模块时进行一些检查,如果某些检查无法让用户决定应该发生什么,则显示一个对话框。

本教程https://platform.netbeans.org/tutorials/60/nbm-login.html启发我为模块创建了安装程序,并将检查和对话框显示到安装程序方法restore()

public class Installer extends ModuleInstall {

    @Override
    public void restored() {
        if (check()) {
            DialogDisplayer.getDefault().notify(myDialogDescriptor);
            //...
        }
    }

这有效,但会导致启动画面关闭,之后会出现异常

java.lang.IllegalStateException: no splash screen available
at java.awt.SplashScreen.checkVisible(SplashScreen.java:197)
at java.awt.SplashScreen.update(SplashScreen.java:324)
at org.netbeans.core.startup.Splash$SplashPainter.repaint(Splash.java:401)
at org.netbeans.core.startup.Splash$SplashPainter$1.run(Splash.java:442)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

我该怎么做才能防止此异常?

1 个答案:

答案 0 :(得分:1)

我能够在一个简单的独立模块中重现此异常。这似乎是known bug in NetBeans。可能的解决方法是使用WindowManager.invokeWhenUIReady()来延迟对话框的显示,直到主窗口打开,就像在此代码示例中一样。

public class Installer extends ModuleInstall {

@Override
public void restored() {
    WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
        @Override
        public void run() {
            NotifyDescriptor.Confirmation dd = new NotifyDescriptor.Confirmation("Do you want to proceed?");
            Object result = DialogDisplayer.getDefault().notify(dd);
            if (result == DialogDescriptor.OK_OPTION) {
                // Do something
            }
        }
    });
}

但是,如果您的要求是在主窗口打开并显示之前显示对话框并采取措施,则此解决方法可能无法接受。