简体   繁体   中英

How can i conditionally prevent a user from navigating to a different view/part in eclipse E4 RCP application?

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.Z93F7 25A07423FE1C889F448B33D21F46Z: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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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