问题
Greetings fellow Stackoverflowians,
I am developing an Eclipse RCP application, and must add a SelectionListener
to the Project Explorer view
the moment after it's created.
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)
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'?
Any opinions and suggestions are appreciated!
回答1:
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.
Eclipse provides the extension point org.eclipse.ui.startup
. It accepts a class that implements the interface org.eclipse.ui.IStartup
. It will be called after the UI has been created, so the ISelectionService
is already available then:
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. 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.
回答2:
You could add your selection listener in the ApplicationWorkbenchWindowAdvisor.postWindowOpen()
method (at this point you can be sure workbench is already created). If you want to add it, when 'Project explorer view' gets visible, then it is possible to do something like this:
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. So one of such solutions could be adding a job, which would wait for the UI to be initializd. 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):
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();
来源:https://stackoverflow.com/questions/19976105/eclipse-rcp-add-a-listener-right-after-a-view-has-been-created