All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jaxx.runtime.swing.navigation.NavigationTreeHandler Maven / Gradle / Ivy

/*
 * *##% 
 * JAXX Runtime
 * Copyright (C) 2008 - 2009 CodeLutin
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * ##%*
 */
package jaxx.runtime.swing.navigation;

import java.awt.Component;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreePath;
import jaxx.runtime.JAXXAction;
import jaxx.runtime.JAXXContext;
import jaxx.runtime.context.JAXXInitialContext;
import jaxx.runtime.JAXXObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * The handler of a navigation tree.
 *
 * This is also the selection model to use, since we must check before moving
 * from a node we can not just listen selection model changed, we must control
 * it.
 *
 * @author tony
 * @since 1.7.2
 */
public abstract class NavigationTreeHandler extends DefaultTreeSelectionModel implements TreeSelectionListener{

    private static final long serialVersionUID = 1L;
    /**
     * Logger
     */
    static private final Log log = LogFactory.getLog(NavigationTreeHandler.class);

    /**
     * Strategy of instanciation of ui.
     * 

* For a given {@code node}, the method {@link #getId(NavigationTreeNode)} * returns the id of ui to use. */ public enum Strategy { /** * instanciate a ui for a node */ PER_NODE { @Override public String getId(NavigationTreeNode node) { return node.getFullPath(); } }, /** * instanciate only one a ui for a type,nodes will share the instanciation */ PER_UI_TYPE { @Override public String getId(NavigationTreeNode node) { return node.getUIClass().getName(); } }; public abstract String getId(NavigationTreeNode node); } /** * UI which contains navigation tree */ protected JAXXContext context; /** * UI Instanciation strategy */ protected Strategy strategy; /** * JAXXContext access helper. * * @since 1.7.2 */ protected NavigationTreeContextHelper contextHelper; protected NavigationTreeHandler(String contextPrefix, JAXXObject context, Strategy strategy) { this.contextHelper = new NavigationTreeContextHelper(contextPrefix); this.context = context; this.strategy = strategy; addTreeSelectionListener(this); } @Override public void valueChanged(TreeSelectionEvent event) { if (log.isDebugEnabled()){ log.debug("Value changed for path : " + event.getPath()); log.debug("Old lead selection path : " + event.getOldLeadSelectionPath()); } if (event.getOldLeadSelectionPath() != null && event.getOldLeadSelectionPath().equals(event.getPath())) { // do not treate this if no path changed return; } NavigationTreeNode node = (NavigationTreeNode) event.getPath().getLastPathComponent(); selectNodeUI(node); } /** * @return le modèle de navigation associé */ protected abstract NavigationModel getNavigationTreeModel(); /** * @return le composent actuellement visible associé au noeud courant ou * au noeud précédent lors d'un changement de noeud. */ protected abstract Component getCurrentUI(); /** * @param node le noeud associé à l'ui à retrouver * @return l'ui associé au novueau noeud sélectionné */ protected abstract Component getUI(NavigationTreeNode node); /** * @param component le composent actuellement visible * @return true si le composent a bien été fermé, false sinon * @throws Exception if any */ protected abstract boolean closeUI(Component component) throws Exception; /** * Instancie une nouvelle ui associé à un noeud de l'arbre de navigation * * @param node le noeud associé à l'ui à créer * @return la nouvelle ui associée au noeud * @throws Exception if any */ protected abstract Component createUI(NavigationTreeNode node) throws Exception; /** * Ouvre l'ui associée au noeud sélectionné dans l'arbre de navigation. * * @param newUI l'ui associé au noeud sélectionné à ouvrir * @param node le node de l'ui a ouvrir * @throws Exception if any */ protected abstract void openUI(Component newUI, NavigationTreeNode node) throws Exception; /** * Traitement des exceptions. * * @param e l'erreur recontrée (ou null si pas d"erreur) */ protected abstract void treateError(Exception e); public JAXXContext getContext() { return context; } public NavigationTreeContextHelper getContextHelper() { return contextHelper; } @Override public void setSelectionPath(TreePath path) { if (path.equals(getSelectionPath())) { // stay on same node, can skip if (log.isDebugEnabled()) { log.debug("skip stay on path " + path); } return; } Component component = getCurrentUI(); try { if (!closeUI(component)) { if (log.isDebugEnabled()) { log.debug("changing node canceled!"); } // can not changed current node return; } if (component instanceof NavigationContentUI) { ((NavigationContentUI) component).closeUI((NavigationTreeNode) path.getLastPathComponent()); } } catch (Exception ex) { treateError(ex); return; } if (log.isDebugEnabled()) { log.debug("will select path " + path); } // ok can safely select the new path super.setSelectionPath(path); } @Override public void setSelectionPaths(TreePath[] paths) { if (paths.equals(getSelectionPaths())) { // stay on same node, can skip if (log.isDebugEnabled()) { log.debug("skip stay on path " + paths); } return; } Component component = getCurrentUI(); try { if (!closeUI(component)) { if (log.isDebugEnabled()) { log.debug("changing node canceled!"); } // can not changed current node return; } if (component instanceof NavigationMultiContentUI) { if (paths.length == 1){ NavigationTreeContextHelper helper = getContextHelper(); ((NavigationMultiContentUI) component).closeUI(helper.getSelectedNodes(getContext())); } } } catch (Exception ex) { treateError(ex); return; } if (log.isDebugEnabled()) { log.debug("will select " + paths.length + " paths"); } // ok can safely select the new path super.setSelectionPaths(paths); } protected void selectNodeUI(NavigationTreeNode node) { try { String path = node.getFullPath(); if (log.isTraceEnabled()) { log.trace(path); } Component newUI = getUI(node); // now, we are free to open the ui associated with the selected node in navigation // get the bean associated with the node Object data = getNavigationTreeModel().getBean(path); // save it in context (must be done before init ui) addSelectedBeanInContext(node, data); if (newUI == null) { // a new ui instance is required newUI = createUI(node); } JAXXContext ctxt = getContext(); NavigationTreeContextHelper helper = getContextHelper(); // save in context current node context path helper.setSelectedPath(ctxt, node.getFullPath()); // save in context current node helper.setSelectedNode(ctxt, node); // save in context current ui // helper.setSelectedUI(ctxt, newUI); // really open the ui associated with the selected node // init ui before to be visible if (newUI instanceof NavigationContentUI) { ((NavigationContentUI) newUI).openUI(node); } // set ui in content openUI(newUI, node); } catch (Exception e) { // remove data from context // if any error, go back to previvous node treateError(e); } } /** * Prepare le context a utiliser pour initialiser une nouvelle ui. * * @param node le noeud associé à l'ui à créer * @return le context à utiliser pour instancier l'ui * @throws Exception if any */ protected JAXXContext createUIContext(NavigationTreeNode node) throws Exception { if (node.getUIHandlerClass() == null) { if (log.isWarnEnabled()) { log.warn("no action associated with ui " + node.getUIClass()); } // no action associated, just return getContext(); } JAXXAction action = node.getUIHandlerClass().newInstance(); // init context with JAXXInitialContext uiContext = action.init(getContext()); return uiContext; } protected void addSelectedBeanInContext(NavigationTreeNode node, Object data) { if (log.isDebugEnabled()) { log.debug("find data for contextPath <" + node.getFullPath() + "> : " + (data == null ? null : data.getClass())); } JAXXContext ctxt = getContext(); NavigationTreeContextHelper helper = getContextHelper(); // remove previous selected bean //TODO-TC-20091004 should have an automatic clean context method while helper.setSelectedBean(ctxt, null); if (data != null) { helper.setSelectedBean(ctxt, data); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy