3

问候 Stackoverflowians 同胞,

我正在开发一个 Eclipse RCP 应用程序,并且必须在它创建后的那一刻添加SelectionListener一个Project Explorer view

我已经意识到我不能在我的贡献插件的 Activator 中执行此操作,而为了获得SelectionServicevia,PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService()我必须有一个活动的工作台窗口(这是调用的null时候)Activator start()

所以我的问题是:我什么时候可以得到SelectionService这样一个Project Explorer view已经创建并且是可见的,但是用户还不能“按下任何按钮”?

任何意见和建议表示赞赏!

4

2 回答 2

5

如果您真的想在启动时跟踪用户选择,而没有可以注册ISelectionListener创建时的 UI(如视图),您可以使用启动挂钩。

Eclipse 提供了扩展点org.eclipse.ui.startup。它接受一个实现接口的类org.eclipse.ui.IStartup。它将在创建 UI 后调用,因此ISelectionService它已经可用:

public class StartupHook implements IStartup, ISelectionListener {

    @Override
    public void earlyStartup() {
        final IWorkbench workbench = PlatformUI.getWorkbench();
        workbench.addWindowListener(new IWindowListener() {

            @Override
            public void windowOpened(IWorkbenchWindow window) {
                addSelectionListener(window);
            }

            @Override
            public void windowClosed(IWorkbenchWindow window) {
                removeSelectionListener(window);
            }
            /* ... */
        });

        workbench.getDisplay().asyncExec(new Runnable() {
            public void run() {
                for (IWorkbenchWindow window : workbench.getWorkbenchWindows()) {
                    addSelectionListener(window);
                }
            }
        });
    }

    private void addSelectionListener(IWorkbenchWindow window) {
        if (window != null) {
            window.getSelectionService().addSelectionListener("org.eclipse.ui.navigator.ProjectExplorer", this);
        }
    }

    private void removeSelectionListener(IWorkbenchWindow window) {
        if (window != null) {
            window.getSelectionService().removeSelectionListener("org.eclipse.ui.navigator.ProjectExplorer", this);
        }
    }

    @Override
    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
        // TODO handle selection changes
        System.out.println("selection changed");
    }
}

请注意,不鼓励使用此 UI 启动挂钩,因为它会强制 OSGi 非常早地激活您的包(以及所有相关的包!)并减慢系统启动速度。因此,请确保您的包裹整洁且纤薄。将捆绑包依赖性降至最低。有时有必要将启动钩子代码移动到一个单独的包中来实现这一点。

于 2013-11-14T13:37:31.480 回答
2

您可以在方法中添加您的选择侦听ApplicationWorkbenchWindowAdvisor.postWindowOpen()器(此时您可以确定已经创建了工作台)。如果要添加它,当“项目资源管理器视图”可见时,可以执行以下操作:

PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().addPartListener(new PartAdapter() {

    @Override
    public void partVisible(IWorkbenchPartReference partRef) {
        if ("org.eclipse.ui.navigator.ProjectExplorer".equals(partRef.getId())) {
            // add selection listener
        }
    }
});

UPD:好的,如果您无权访问 AppliationWorkbenchWindowAdvisor(这很奇怪,如果您正在开发 Eclipse RCP 产品),那么 ASAIK,没有干净的解决方案来获得有关 UI 可用性的通知。因此,其中一种解决方案可能是添加一个作业,该作业将等待 UI 初始化。在您的插件Activator.start()方法中考虑添加以下作业(确保您可以将其提取到单独的类并以多种方式改进,但一开始应该就足够了):

Job j = new Job("") {

    @Override
    protected IStatus run(IProgressMonitor monitor) {
        final boolean[] workbenchAvailable = new boolean[] { false };
        Display.getDefault().syncExec(new Runnable() {

            @Override
            public void run() {
                if (PlatformUI.isWorkbenchRunning() && PlatformUI.getWorkbench().getActiveWorkbenchWindow() != null) {
                    workbenchAvailable[0] = true;
                }

            }
        });
        if (workbenchAvailable[0]) {
            System.out.println("Workbench is available");
            Display.getDefault().asyncExec(new Runnable() {

                @Override
                public void run() {
                    ISelectionService selectionService =
                        PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService();

                    System.out.println(selectionService);
                }
            });
        } else {
            System.out.println("Waiting for the Workbench ...");
            schedule(1000);
        }
        return Status.OK_STATUS;
    }
};

j.schedule();
于 2013-11-14T12:19:09.127 回答