使用简单的代码示例

时间:2015-10-15 20:23:48

标签: java eclipse swt

我正在通过示例初学者指南“Eclipse 4 Plug-in Development”中的练习。我进入了标题为“操作时间 - 将项目添加到托盘”的部分,当我运行测试实例时,我开始看到这样的错误:

org.eclipse.swt.SWTError: Not implemented [multiple displays]
at org.eclipse.swt.SWT.error(SWT.java:4308)
at org.eclipse.swt.widgets.Display.checkDisplay(Display.java:760)
at org.eclipse.swt.widgets.Display.create(Display.java:896)
at org.eclipse.swt.graphics.Device.<init>(Device.java:157)

我一直在阅读有关此错误消息的一些参考资料,但我仍然不确定我能做些什么。

练习中指定的更改会在“Activator”类的“start”和“stop”方法中调用“Display.getDefault()”,这类方法扩展了AbstractUIPlugin。我确认注释掉这些新更改会删除错误。我还尝试了将“Display.getDefault()”存储为实例var并重复使用的简单更改,而不是每次在“start”和“stop”中调用“Display.getDefault()”。这没有任何影响(我不知道这是不是一个好主意)。

这是该类的当前状态,其中一些旧块已注释掉:

public class Activator extends AbstractUIPlugin {
    private TrayItem    trayItem;
    private Image       image;
    private Display     display;

    public static final String PLUGIN_ID = "com.packtpub.e4.clock.ui"; //$NON-NLS-1$

    private static Activator plugin;

    public void setDisplay(Display display) {this.display = display;}
    public Display getDisplay() {return display;}

    public Activator() {}

    public void start(BundleContext context) throws Exception {
        super.start(context);
        plugin = this;

//      final Display   display = Display.getDefault();
        setDisplay(Display.getDefault());
        getDisplay().asyncExec(new Runnable() {
            public void run() {
                image = new Image(getDisplay(), Activator.class
                        .getResourceAsStream("/icons/sample.gif"));
                Tray    tray    = getDisplay().getSystemTray();
                if (tray != null && image != null) {
                    trayItem    = new TrayItem(tray, SWT.NONE);
                    trayItem.setToolTipText("Hello World");
                    trayItem.setVisible(true);
                    trayItem.setText("Hello World");
//                  trayItem.setImage(new Image(trayItem.getDisplay(),
//                          Activator.class.getResourceAsStream("/icons/sample.gif")));
                    trayItem.setImage(image);
                }
            }
        });
    }

    public void stop(BundleContext context) throws Exception {
        if (trayItem != null && !trayItem.isDisposed()) {
//          Display.getDefault().asyncExec(new Runnable() {
            getDisplay().asyncExec(new Runnable() {
                public void run() {
                    if (trayItem != null && !trayItem.isDisposed())
                        trayItem.dispose();
                }
            });
        }
        if (image != null && !image.isDisposed()) {
//          Display.getDefault().asyncExec(new Runnable() {
            getDisplay().asyncExec(new Runnable() {
                public void run() {
                    if (image != null && !image.isDisposed())
                        image.dispose();
                }
            });
        }
    }

    public static Activator getDefault() {return plugin;}

    public static ImageDescriptor getImageDescriptor(String path) {
        return imageDescriptorFromPlugin(PLUGIN_ID, path);
    }
}

更新

当尝试创建多个“Display”对象时,会出现这种情况,我在Display类的两个构造函数中设置断点。

由于在我的Activator类中调用了“Display.getDefault()”,我点击了断点,但是在我的“start”方法完成之后,我也用以下堆栈点击它:

Thread [main] (Suspended (breakpoint at line 500 in Display))   
    Display.<init>(DeviceData) line: 500    
    Workbench.createDisplay() line: 714 
    PlatformUI.createDisplay() line: 161    
    IDEApplication.createDisplay() line: 153    
    IDEApplication.start(IApplicationContext) line: 95  
    EclipseAppHandle.run(Object) line: 196  
    EclipseAppLauncher.runApplication(Object) line: 110 
    EclipseAppLauncher.start(Object) line: 79   
    EclipseStarter.run(Object) line: 344    
    EclipseStarter.run(String[], Runnable) line: 179    
    NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
    NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57  
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43  
    Method.invoke(Object, Object...) line: 606  
    Main.invokeFramework(String[], URL[]) line: 622 
    Main.basicRun(String[]) line: 577   
    Main.run(String[]) line: 1410   
    Main.main(String[]) line: 1386  

当我从这个断点恢复时,我看到“多个显示”错误。因此,错误不会发生在我的班级中,它会在稍后发生,当时正在创建另一个人物。

更新

当我继续阅读本书中的练习时,我在自定义视图的“createPartControl()”方法中遇到了另一个调用“Display.getDefault()”的代码块。我想知道这里会发生什么。使用我在两个Display构造函数中的现有断点以及“getDefault()”中的一个断点,并在我的“Activator”类中注释掉有问题的代码,我在启动测试实例时看到的是第一次调用Display构造函数就在此之前的堆栈跟踪中,来自“IDEApplication.createDisplay()”。之后,它进入了我的视图创建,但是对“Display.getDefault()”的调用没有创建新的显示,因为它已经存在。

从我到目前为止所看到的,将代码放入调用“Display.getDefault()”的bundle Activator类似乎不是一个好主意,因为当IDEApplication完全启动时,它会强制执行显示的创建,将失败。

0 个答案:

没有答案