I am trying to prevent a user from going to a different view/part in a perspective of eclipse E4 application.When i am trying to navigate to the same perspective and view,I am facing a stackOverflow exception due to recursively calling the showPart method by the framework.
NavigationHelper.showPerspective(CommonConstants.PERSPECTIVE1, getEclipseContext());
NavigationHelper.showPart(CommonConstants.VIEW1, getEclipseContext());
NavigationHelper.showPart(CommonConstants.VIEW2, getEclipseContext());
My showPart
method lokks like this,
public static boolean showPart(String partId, IEclipseContext eclipseContext) {
logger.debug("showPart::STARTED::" + partId);
if (null == eclipseContext) {
eclipseContext = getEclipseContext();
}
if (Model.getInstance().hasDataChanged()) {
if (partId.equalsIgnoreCase(CommonConstants.VIEW1)
|| partId.equalsIgnoreCase(CommonConstants.VIEW2)) {
isNavigationSuccessful = true;
} else {
isNavigationSuccessful = false;
Navigation.showWarning();
}
}
if (isNavigationSuccessful) {
findPartAndActivate(partId, eclipseContext, true);
}
logger.debug("isNavigationSuccessful = " + isNavigationSuccessful);
logger.debug("showPart::END::" + partId);
return isNavigationSuccessful;
}
The findPartAndActivate looks like this
private static boolean findPartAndActivate(String partId, IEclipseContext eclipseContext, boolean giveFocus) {
MTrimmedWindow applicationWindow = ((MTrimmedWindow) ((MApplication) eclipseContext.get(MApplication.class))
.getChildren().get(0));
IEclipseContext currentContext = applicationWindow.getContext();
EPartService partService = currentContext.get(EPartService.class);
EModelService modelService = currentContext.get(EModelService.class);
MPart part = (MPart) modelService.find(partId, eclipseContext.get(MApplication.class).getChildren().get(0));
partService.activate(part, giveFocus);
return true;
}
The partDeactivated is invoked,once a user leaves from a part/View
public void partDeactivated(@Active MPart part) {
if (partInstance.getElementId() != part.getElementId()) {
return;
}
if (transactionButton != null && !transactionButton.isDisposed() && transactionButton.isEnabled()
&& isTransactionCompleted && NavigationHelper.getEditableViewInstance() != null && !partDeactivateFlag) {
doTransaction();
partDeactivateFlag = true;
}
if (Navigation.isPerspective()) {
if (EModel.getInstance().hasDataChanged()/*&& !Model.getInstance().isSwitchFlag()*/) {
System.out.println("Changes");
//Model.getInstance().setSwitchFlag(true);
//partDeactivateFlag = true;
NavigationHelper.showPerspective(CommonConstants.PERSPECTIVE1, getEclipseContext());
NavigationHelper.showPart(CommonConstants.VIEW1, getEclipseContext());
NavigationHelper.showPart(CommonConstants.VIEW2, getEclipseContext());
}
}
viewDeactivated();
}
};
java.lang.StackOverflowError : null org.eclipse.e4.ui.workbench.modeling.ElementMatcher.select(ElementMatcher.java:71) org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.findElementsRecursive(ModelServiceImpl.java:182) org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.findElementsRecursive(ModelServiceImpl.java:317) org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.findElementsRecursive(ModelServiceImpl.java:271) org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.findElementsRecursive(ModelServiceImpl.java:271) org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.findElementsRecursive(ModelServiceImpl.java:271) org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.findElementsRecursive(ModelServiceImpl.java:251) org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.findElementsRecursive(ModelServiceImpl.java:271) org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.findElements(ModelServiceImpl.java:428) org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.findElements(ModelServiceImpl.java:409) org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.findElements(ModelServiceImpl.java:414) org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.find(ModelServiceImpl.java:448)
This is the StackOverflow trace..
How can I solve this..?
Well the stack trace shows this is an error in your code. You are running NavigationHelper.showPart
in a part deactivated listener, but your code is causing another part deactivate event which calls the deactivate listener again which calls showPart again and so on.
You can't try to show a different part in the the part deactivate listener directly.
One possibility is to use Display.asyncExec
in the part deactivate listener to run the showPart after the deactivate event has completed.