/** * Returns the current navigation state reported by this Navigator's * {@link NavigationStateManager}. * * @return The navigation state. */ public String getState() { return getStateManager().getState(); }
/** * Returns the parameters for the view being activated parsed to a map, * using {@literal &} as the parameter separator character. * * @return navigation parameters (potentially bookmarkable) for the new * view * @since 8.1 */ public Map<String, String> getParameterMap() { return getParameterMap("&"); }
/** * Returns the navigator that triggered this event. * * @return Navigator (not null) */ public Navigator getNavigator() { return (Navigator) getSource(); }
@Override public void setNavigator(Navigator navigator) { if (this.navigator == null && navigator != null) { uriFragmentRegistration = page.addUriFragmentChangedListener( event -> navigator.navigateTo(getState())); } else if (this.navigator != null && navigator == null) { uriFragmentRegistration.remove(); } this.navigator = navigator; }
@Override public void setNavigator(Navigator navigator) { if (popStateListenerRegistration != null) { popStateListenerRegistration.remove(); popStateListenerRegistration = null; } if (navigator != null) { popStateListenerRegistration = ui.getPage().addPopStateListener( event -> navigator.navigateTo(getState())); } }
/** * Returns the parameters for the view being activated parsed to a map, * using the given string as the parameter separator character. * * @param separator * the parameter separator string to use * @return navigation parameters (potentially bookmarkable) for the new * view * @since 8.1 */ public Map<String, String> getParameterMap(String separator) { return getNavigator().parseParameterStringToMap(getParameters(), separator); } }
/** * Revert the changes to the navigation state. When navigation fails, this * method can be called by {@link #navigateTo(View, String, String)} to * revert the URL fragment to point to the previous view to which navigation * succeeded. * * This method should only be called by * {@link #navigateTo(View, String, String)}. Normally it should not be * overridden, but can be by frameworks that need to hook into view change * cancellations of this type. * * @since 7.6 */ protected void revertNavigation() { if (currentNavigationState != null) { getStateManager().setState(currentNavigationState); } }
/** * Update the internal state of the navigator to reflect the actual * switching of views. * * This method should only be called by * {@link #navigateTo(View, String, String)} between showing the view and * calling {@link View#enter(ViewChangeEvent)}. If this method is * overridden, the overriding version must call the super method. * * @since 7.6 * @param event * a view change event with details of the change */ protected void switchView(ViewChangeEvent event) { currentView = event.getNewView(); }
@Override public void showView(View view) { container.setContent(view.getViewComponent()); } }
/** * Internal method activating a view, setting its parameters and calling * listeners. * <p> * This method also verifies that the user is allowed to perform the * navigation operation. * * @param view * view to activate * @param viewName * (optional) name of the view or null not to change the * navigation state * @param parameters * parameters passed in the navigation state to the view */ protected void navigateTo(View view, String viewName, String parameters) { runAfterLeaveConfirmation( () -> performNavigateTo(view, viewName, parameters)); }
/** * Registers a view that is displayed when no other view matches the * navigation state. This implicitly sets an appropriate error view provider * and overrides any previous {@link #setErrorProvider(ViewProvider)} call. * * @param view * The View that should be used as the error view. */ public void setErrorView(final View view) { setErrorProvider(new ViewProvider() { @Override public View getView(String viewName) { return view; } @Override public String getViewName(String navigationState) { return navigationState; } }); }
/** * Creates a navigator that is tracking the active view using URI fragments * of the {@link Page} containing the given UI and replacing the contents of * a {@link SingleComponentContainer} with the active view. * <p> * Views must implement {@link Component} when using this constructor. * <p> * Navigation is automatically initiated after {@code UI.init()} if a * navigator was created. If at a later point changes are made to the * navigator, {@code navigator.navigateTo(navigator.getState())} may need to * be explicitly called to ensure the current view matches the navigation * state. * * @param ui * The UI to which this Navigator is attached. * @param container * The SingleComponentContainer whose contents should be replaced * with the active view on view change */ public Navigator(UI ui, SingleComponentContainer container) { this(ui, new SingleComponentContainerViewDisplay(container)); }
@Override public void setState(String state) { setFragment("!" + state); }
/** * Check whether view change is allowed by view change listeners ( * {@link ViewChangeListener#beforeViewChange(ViewChangeEvent)}). * * This method can be overridden to extend the behavior, and should not be * called directly except by {@link #navigateTo(View, String, String)}. * * @since 7.6 * @param event * the event to fire as the before view change event * @return true if view change is allowed */ protected boolean beforeViewChange(ViewChangeEvent event) { return fireBeforeViewChange(event); }
/** * Returns the current navigation state reported by this Navigator's * {@link NavigationStateManager} as Map<String, String> where each key * represents a parameter in the state. * * Uses {@literal &} as parameter separator. If the state contains * {@literal #!view/foo&bar=baz} then this method will return a map * containing {@literal foo => ""} and {@literal bar => baz}. * * @return The parameters from the navigation state as a map * @see #getStateParameterMap(String) * @since 8.1 */ public Map<String, String> getStateParameterMap() { return getStateParameterMap(DEFAULT_STATE_PARAMETER_SEPARATOR); }
/** * Performs the navigation which triggered the event in the first place. */ public void navigate() { if (navigateRun) { throw new IllegalStateException( "navigate() can only be called once"); } action.run(); navigateRun = true; }
@Override public String getState() { String fragment = getFragment(); if (fragment == null || !fragment.startsWith("!")) { return ""; } else { return fragment.substring(1); } }
/** * Creates view change event for given {@code view}, {@code viewName} and * {@code parameters}. * * @since 7.6.7 */ public void destroy() { stateManager.setNavigator(null); ui.setNavigator(null); }
@Override public void showView(View view) { container.removeAllComponents(); container.addComponent(view.getViewComponent()); } }