问题
I am trying to provide a command/ handler to switch to a specific Perspective.
I came up with the following class:
public class OpenPerspectiveHandler {
private static final Logger logger = Logger.getLogger(OpenPerspectiveHandler.class);
@Inject
private MApplication application;
@Inject
private EModelService modelService;
@Inject
private EPartService partService;
private final String perspectiveId;
public OpenPerspectiveHandler(String perspectiveId) {
super();
this.perspectiveId = perspectiveId;
}
public void changePerspective(String perspectiveId) {
Optional<MPerspective> perspective = findPerspective();
if(perspective.isPresent()) {
partService.switchPerspective(perspective.get());
} else {
logger.debug("Perspective not found (" + perspectiveId + ")");
}
}
@Execute
public void execute() {
changePerspective(perspectiveId);
}
private Optional<MPerspective> findPerspective() {
MUIElement element = modelService.find(perspectiveId, application);
if(element instanceof MPerspective) {
return Optional.of((MPerspective)element);
} else {
logger.debug("Wrong type " + element);
}
return Optional.empty();
}
@Override
public String toString() {
return "OpenPerspectiveHandler [application=" + application + ", modelService=" + modelService + ", partService=" + partService + ", perspectiveId=" + perspectiveId + "]";
}
}
Interestingly, this works only once. A workaround is to cache MPerspective
once it was found and not to use modelService.find(perspectiveId, application)
again.
Why does it work only once? modelService.find(perspectiveId, application)
returns null
after the first execution.
EDIT:
Another approach (as suggested by greg-449) is the following:
public class OpenPerspectiveHandler {
private static final Logger logger = Logger.getLogger(OpenPerspectiveHandler.class);
private final String perspectiveId;
public OpenPerspectiveHandler(String perspectiveId) {
super();
this.perspectiveId = perspectiveId;
}
@Execute
public void changePerspective(MApplication application, EModelService modelService, EPartService partService) {
Optional<MPerspective> perspective = findPerspective(application, modelService);
if(perspective.isPresent()) {
partService.switchPerspective(perspective.get());
} else {
logger.debug("Perspective not found (" + perspectiveId + ")");
}
}
private Optional<MPerspective> findPerspective(MApplication application, EModelService modelService) {
MUIElement element = modelService.find(perspectiveId, application);
if(element instanceof MPerspective) {
return Optional.of((MPerspective)element);
} else {
logger.debug("Wrong type " + element);
}
return Optional.empty();
}
}
But this approach also changes the perspective only once. modelService.find(perspectiveId, application);
returns null
after the first execution.
回答1:
The EPartService
varies depending on the context that the handler runs in. In some cases you get the Application part service which only works if there is an active window.
You can get the part service for that window using something like:
MWindow window = (MWindow)modelService.find("top window id", application);
IEclipseContext windowContext = window.getContext();
EPartService windowPartService = windowContext.get(EPartService.class);
来源:https://stackoverflow.com/questions/44927967/open-perspective-programmatically