简体   繁体   English

Eclipse RCP - 在创建视图后立即添加监听器

[英]Eclipse RCP - add a Listener right after a View has been created

Greetings fellow Stackoverflowians, 问候Stackoverflowians,

I am developing an Eclipse RCP application, and must add a SelectionListener to the Project Explorer view the moment after it's created. 我正在开发Eclipse RCP应用程序,并且必须在创建后立即将SelectionListener添加到Project Explorer view

I've realized that I cannot do this in the Activator of my contributing plug-in, whereas in order to get the SelectionService via PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService() I must have an active workbench window (which is null when the Activator start() is called) 我已经意识到我不能在我的贡献插件的Activator中执行此操作,而为了通过PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService()获取SelectionService PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService()我必须有一个活动的工作台窗口(这是调用Activator start()时返回null

So my question: When can I get the SelectionService so that the Project Explorer view has been created and is visible, but the user has not yet been able to 'push any buttons'? 所以我的问题是:我什么时候可以获得SelectionService以便创建Project Explorer view并且可见,但是用户还没有能够“按任何按钮”?

Any opinions and suggestions are appreciated! 任何意见和建议表示赞赏!

When you really want to track user selection from startup without having a UI (like a view) that can register an ISelectionListener on creation, you can us a startup hook. 如果您真的想要从启动时跟踪用户选择而没有可以在创建时注册ISelectionListener的UI(如视图),那么您可以使用启动挂钩。

Eclipse provides the extension point org.eclipse.ui.startup . Eclipse提供了扩展点org.eclipse.ui.startup It accepts a class that implements the interface org.eclipse.ui.IStartup . 它接受一个实现接口org.eclipse.ui.IStartup It will be called after the UI has been created, so the ISelectionService is already available then: 它将在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");
    }
}

Note that it is discouraged to use this UI startup hook as it forces OSGi to activate your bundle very early (and so all dependent bundles too!) and slows down system startup. 请注意, 不鼓励使用此UI启动挂钩,因为它迫使OSGi很早就激活您的捆绑包(所以所有依赖捆绑包也是如此!)并减慢系统启动速度。 So please make sure that your bundle is neat and slim. 所以请确保你的包很整齐。 Reduce bundle dependencies to a minimum. 将捆绑依赖性降至最低。 Sometimes it is necessary move the startup hook code into a separate bundle to achieve that. 有时需要将启动钩子代码移动到一个单独的包中以实现这一点。

You could add your selection listener in the ApplicationWorkbenchWindowAdvisor.postWindowOpen() method (at this point you can be sure workbench is already created). 您可以在ApplicationWorkbenchWindowAdvisor.postWindowOpen()方法中添加您的选择侦听器(此时您可以确定已创建工作台)。 If you want to add it, when 'Project explorer view' gets visible, then it is possible to do something like this: 如果要添加它,当“Project explorer view”可见时,则可以执行以下操作:

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: OK, if you don't have access to AppliationWorkbenchWindowAdvisor (which is weird, if you are developing Eclipse RCP product), then ASAIK, there is no clean solution to get notified about availability of the UI. UPD:好的,如果您无法访问AppliationWorkbenchWindowAdvisor(这很奇怪,如果您正在开发Eclipse RCP产品),那么ASAIK,没有干净的解决方案可以获得有关UI可用性的通知。 So one of such solutions could be adding a job, which would wait for the UI to be initializd. 因此,其中一个解决方案可能是添加一个等待UI初始化的作业。 In your plugin Activator.start() method consider adding following job (sure you can extract it to separate class and improve in many ways, but for the beginning it should be sufficient): 在你的插件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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM