Eclipse RCP系统托盘IllegalArgumentException

时间:2017-09-05 18:36:18

标签: java thread-safety swt eclipse-rcp

此代码用于与Eclipse Kepler一起使用。但是编写它的开发人员已经不见了,它不再使用升级到Neon插件了。我得到了这个例外:

Caused by: org.eclipse.swt.SWTException: Failed to execute runnable (java.lang.IllegalArgumentException: Argument cannot be null)
at org.eclipse.swt.SWT.error(SWT.java:4533)
at org.eclipse.swt.SWT.error(SWT.java:4448)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:185)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4536)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4154)
at com.example.server.commons.SysTrayThread.localRun(SysTrayThread.java:141)
at com.example.server.commons.SysTrayThread$2.run(SysTrayThread.java:87)

使用此代码:

private static final String SYSTEM_BUNDLE_ID = "org.eclipse.osgi"; //$NON-NLS-1$

private volatile boolean working = true;

private final Bundle bundle;
private final String logoPath;

private Display display;

public SysTrayThread (final Bundle bundle, final String logoPath) {
    this.bundle = bundle;
    this.logoPath = logoPath;
}

@Override
public void run() {
    if(System.getProperty("os.name").equals("Mac OS X")) {
        Class<?> comAppleConcurrentDispatch = null;
        try {
            comAppleConcurrentDispatch = Class.forName("com.apple.concurrent.Dispatch");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Method getInstance = null;
        Object dispatchInstance = null;
        Method getNonBlockingMainQueueExecutor = null;
        Executor executor = null;
        try {
            getInstance = comAppleConcurrentDispatch.getMethod("getInstance", (Class<?>[]) null);
            dispatchInstance = getInstance.invoke(null, (Object[]) null);
            getNonBlockingMainQueueExecutor = dispatchInstance.getClass().getMethod("getNonBlockingMainQueueExecutor",(Class<?>[]) null);
            executor = (Executor) getNonBlockingMainQueueExecutor.invoke(dispatchInstance, (Object[]) null);
            executor.execute(new Runnable() {
                public void run() {
                    try {
                        localRun();
                    } catch(Throwable t) {

                    }
                }
            }
            );
        } catch (IllegalAccessException | IllegalArgumentException
                | InvocationTargetException | NoSuchMethodException | SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } else {
        Display.getDefault().asyncExec(new Runnable() {
            @Override
            public void run() {
                localRun();
            }
        });
    }

}

public void localRun() 
{
    try {
        SysTrayThread.this.display = Display.getDefault();
    } catch (org.eclipse.swt.SWTError ex) {
        return;
    }

    URL url = SysTrayThread.this.bundle.getEntry(SysTrayThread.this.logoPath);
    try {
        Image image = null;
        Shell shell = new Shell(SysTrayThread.this.display);

        InputStream stream = url.openStream();
        try {
            image = new Image(SysTrayThread.this.display, new ImageData(stream));
        } finally {
            stream.close();
        }

        final Menu menu = new Menu(shell, SWT.POP_UP);
        MenuItem exitMenuItem = new MenuItem(menu, SWT.PUSH);
        exitMenuItem.setText(Messages.SHUTDOWN_MENU_ITEM);
        exitMenuItem.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(final SelectionEvent event) {
                Bundle bundle = Platform.getBundle(SysTrayThread.SYSTEM_BUNDLE_ID);
                try {
                    bundle.stop();
                } catch (BundleException ex) {
                    throw new RuntimeException(ex);
                }
            }

        });
        Tray tray = SysTrayThread.this.display.getSystemTray();
        TrayItem trayItem = new TrayItem(tray, SWT.NONE);
        trayItem.addListener(SWT.MenuDetect, new Listener() {

            @Override
            public void handleEvent(final Event event) {
                menu.setVisible(true);
            }
        });
        trayItem.setImage(image);
        while (SysTrayThread.this.working && !shell.isDisposed()) {
            if (!SysTrayThread.this.display.readAndDispatch()) { // line 141
                SysTrayThread.this.display.sleep();
            }
        }
        tray.dispose();
        image.dispose();
        if (!shell.isDisposed()) {
            shell.dispose();
        }
    } catch (IOException ex) {
        throw new RuntimeException(ex);
    }
}

public void setWorking(final boolean working) {
    if (this.display != null) {
        this.display.syncExec(new Runnable() {

            @Override
            public void run() {
                SysTrayThread.this.display.close();
            }
        });
    }
    this.working = working;
}

我查看了有关此问题的RCP特定信息,但答案与将SWT元素设置为null有关。如您所见,我没有设置值,只需调用readAndDispatch()。

有什么想法吗?

0 个答案:

没有答案