/** * Unsubscribe from all events. This also unsubscribes the internal model and all internal views */ public void unsubscribeAll() { unsubscribe(); for (AbstractWizardPanelView view : getWizardViewMap().values()) { view.unsubscribe(); } getWizardModel().unsubscribe(); }
/** * Show the named panel * * <p>This is guaranteed to be on the EDT * * @param panelName The panel name */ public void show(String panelName) { Preconditions.checkState( SwingUtilities.isEventDispatchThread(), "This method should run on the EDT"); if (!wizardViewMap.containsKey(panelName)) { log.error( "'{}' is not a valid panel name. Check the panel has been registered in the view map. Registered panels are\n{}", wizardViewMap.keySet()); return; } final AbstractWizardPanelView wizardPanelView = wizardViewMap.get(panelName); if (!wizardPanelView.isInitialised()) { // Initialise the wizard screen panel and add it to the card layout parent wizardScreenHolder.add(wizardPanelView.getWizardScreenPanel(true), panelName); } // De-register any existing default buttons from previous panels wizardPanelView.deregisterDefaultButton(); // Provide warning that the panel is about to be shown if (wizardPanelView.beforeShow()) { // No abort so show (use info to assist with FEST debugging) log.info("Showing wizard panel: {}", panelName); cardLayout.show(wizardScreenHolder, panelName); // We must ensure that all other EDT processing has completed before // calling afterShow() to guarantee visibility of components // Failure to do this causes problems with popovers during startup SwingUtilities.invokeLater( new Runnable() { @Override public void run() { wizardPanelView.afterShow(); } }); } }
/** * Hide the wizard if <code>beforeHide</code> returns true * * <p>Guaranteed to run on the EDT * * @param panelName The panel name * @param isExitCancel True if this hide operation comes from an exit or cancel */ public void hide(final String panelName, final boolean isExitCancel) { log.debug("Hide requested for {} with exitCancel {} ", panelName, isExitCancel); if (!wizardViewMap.containsKey(panelName)) { log.error( "'{}' is not a valid panel name. Check the panel has been registered in the view map. Registered panels are\n{}", wizardViewMap.keySet()); return; } final AbstractWizardPanelView wizardPanelView = wizardViewMap.get(panelName); // Provide warning that the panel is about to be hidden if (wizardPanelView.beforeHide(isExitCancel)) { // No cancellation so go ahead with the hide handleHide(panelName, isExitCancel, wizardPanelView); } }
/** * Hide the wizard * * <p>This method is guaranteed to run on the EDT * * @param panelName The panel name * @param isExitCancel True if this hide operation comes from an exit or cancel * @param wizardPanelView The wizard panel view from the wizard view map */ protected void handleHide( final String panelName, final boolean isExitCancel, AbstractWizardPanelView wizardPanelView) { log.debug("Handle hide starting: '{}' ExitCancel: {}", panelName, isExitCancel); // De-register wizardPanelView.deregisterDefaultButton(); // Ensure we unsubscribe the wizard from all further events getWizardModel().unsubscribe(); unsubscribe(); // Issue the wizard hide event before the hide takes place to give panel views time to update ViewEvents.fireWizardHideEvent(panelName, wizardModel, isExitCancel); // Required to run on a new thread since this may take some time to complete wizardHideExecutorService.submit( new Runnable() { @Override public void run() { log.debug("Hide and deregister wizard: '{}'", this.getClass().getSimpleName()); // Require some extra time to get the rest of the UI started for credentials wizard // There is no chance of the system showing a light box during this time so this // operation is safe if (CredentialsState.CREDENTIALS_ENTER_PASSWORD.name().equals(panelName)) { log.trace("Blocking to allow UI startup to complete"); Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS); } // Work through the view map ensuring all components are deregistered from UI events log.trace("Deregister {} views and their component(s)", wizardViewMap.size()); for (Map.Entry<String, AbstractWizardPanelView> entry : wizardViewMap.entrySet()) { AbstractWizardPanelView panelView = entry.getValue(); // Ensure we deregister the wizard panel view (and model if present) for events try { // Unsubscribe from events panelView.unsubscribe(); log.trace( "Deregistered wizard panel view '{}' from UI events", panelView.getPanelName()); if (panelView.getPanelModel().isPresent()) { Object panelModel = panelView.getPanelModel().get(); // May get some false positives from this approach CoreEvents.unsubscribe(panelModel); log.trace( "Deregistered wizard panel model '{}' from UI events", panelView.getPanelName()); } } catch (NullPointerException | IllegalArgumentException e) { log.warn( "Wizard panel model/view '{}' was not registered", panelView.getPanelName(), e); } // Deregister all components @SuppressWarnings("unchecked") List<ModelAndView> mavs = panelView.getComponents(); for (ModelAndView mav : mavs) { mav.unsubscribe(); } log.trace( "Closed {} registered component(s) from wizard panel view '{}'", mavs.size(), panelView.getPanelName()); // Remove the references mavs.clear(); } // Depopulate the map to ensure non-AWT references are removed wizardViewMap.clear(); // Hiding the light box must be on the EDT SwingUtilities.invokeLater( new Runnable() { @Override public void run() { log.trace("Handle hide remove light box: '{}'", panelName); // This removes the reference to the wizard allowing for garbage collection Panels.hideLightBoxIfPresent(); // Clear the deferred hide Panels.setDeferredHideEventInProgress(false); } }); } }); }