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

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

There is a newer version: 3.0-alpha-6
Show newest version
/*
 * *##% 
 * 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.lang.reflect.InvocationTargetException;
import java.util.Enumeration;
import java.util.regex.Pattern;
import javax.swing.JTree;
import javax.swing.tree.TreePath;
import jaxx.runtime.JAXXContext;
import jaxx.runtime.JAXXObject;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdesktop.swingx.JXTreeTable;

/**
 * Helper object associated to a given navigation tree system.
 *
 * To helper is context safe (base on a {@link NavigationTreeContextHelper}.
 * 
 * @author chemit
 * @since 1.7.2
 * @see NavigationTreeModel
 */
public abstract class NavigationTreeHelper extends NavigationTreeContextHelper {

    /**
     * Logger
     */
    static private final Log log =
            LogFactory.getLog(NavigationTreeHelper.class);

    /**
     * Create the model.
     *
     * @param context the context to associate with fresh model
     * @return the new model build with data from the given context
     */
    public abstract NavigationModel createTreeModel(JAXXContext context);

    /**
     * Create the tree handler.
     *
     * @param context the context to associate with fresh handler
     * @return the new handler
     */
    public abstract NavigationTreeHandler createTreeHandler(JAXXObject context);

    public NavigationTreeHelper(String contextPrefix) {
        super(contextPrefix);
    }

    public Object getContextValue(JAXXContext context, String path)
            throws InvocationTargetException, NoSuchMethodException,
            IllegalAccessException {
        NavigationModel treeModel = getSafeModel(context);
        return treeModel.getBean(path);
    }

    public NavigationTreeNode findNode(JAXXContext context, String path) {
        NavigationModel treeModel = getSafeModel(context);
        return treeModel.findNode(path);
    }

    public NavigationTreeNode findNode(JAXXContext context, String path,
                                       String regex) {
        NavigationModel treeModel = getSafeModel(context);
        return treeModel.findNode(path, regex);
    }

    public NavigationTreeNode findNode(JAXXContext context, String path,
                                       Pattern regex) {

        NavigationModel treeModel = getSafeModel(context);
        return treeModel.findNode(path, regex);
    }

    public NavigationTreeNode findNode(JAXXContext context, String path,
                                       String regex, String suffix) {

        NavigationModel treeModel = getSafeModel(context);

        NavigationTreeNode navigationTreeNode = treeModel.findNode(path, regex);
        if (navigationTreeNode != null && suffix != null) {
            navigationTreeNode = treeModel.findNode(navigationTreeNode, suffix);
        }
        return navigationTreeNode;
    }

    public NavigationTreeNode findNode(JAXXContext context, String path,
                                       Pattern regex, String suffix) {

        NavigationModel treeModel = getSafeModel(context);

        NavigationTreeNode navigationTreeNode = treeModel.findNode(path, regex);
        if (navigationTreeNode != null && suffix != null) {
            navigationTreeNode = treeModel.findNode(navigationTreeNode, suffix);
        }
        return navigationTreeNode;
    }

    /**
     * Sélection d'un noeud dans l'arbre de navigation à partir de son path.
     *
     * @param context le contexte applicatif
     * @param path le path absolue du noeud dans l'arbre
     */
    public void selectNode(JAXXContext context, String path) {
        NavigationTreeNode node = findNode(context, path);
        if (log.isDebugEnabled()) {
            log.debug(path + " :: " + node);
        }
        if (node != null) {
            selectNode(context, node);
        }
    }

    /**
     * Sélection d'un noeud dans l'arbre de navigation.
     *
     * @param context le contexte applicatif
     * @param node le noeud à sélectionner dans l'arbre
     */
    public void selectNode(JAXXContext context, NavigationTreeNode node) {


        NavigationModel navigationModel = getSafeModel(context);
        if (log.isDebugEnabled()) {
            log.debug(node);
        }
        TreePath path = new TreePath(navigationModel.getPathToRoot(node));
        JTree tree = getTree(context);
        if (tree == null){
            // FIXME : Refactor in other helper ?
            // If its JXTreeTable
            JXTreeTable treeTable = getSafeTreeTable(context);
            treeTable.getTreeSelectionModel().setSelectionPath(path);
            treeTable.scrollPathToVisible(path);
            return;
        }
        tree.setSelectionPath(path);
        tree.scrollPathToVisible(path);
    }

    /**
     * Sélection du parent du noeud selectionne dans l'arbre de navigation.
     *
     * @param context le contexte applicatif
     */
    public void gotoParentNode(JAXXContext context) {

        NavigationTreeNode node = getSelectedNode(context);

        if (node == null) {
            // pas de noeud selectionne
            throw new NullPointerException("no selected node in context");
        }
        node = node.getParent();

        selectNode(context, node);
    }

    /**
     * Obtain the first ancestor with the matching internalClass
     *
     * @param current   the node to test
     * @param beanClass the type of the internal class to seek of
     * @return the first ancestor node with the matching class or
     *         {@code null} if not found
     */
    public NavigationTreeNode getParentNode(NavigationTreeNode current,
                                            Class beanClass) {
        if (current == null) {
            // ancestor not found
            return null;
        }
        if (beanClass.isAssignableFrom(current.getInternalClass())) {
            // matching node
            return current;
        }
        // try in the parent of node
        return getParentNode(current.getParent(), beanClass);
    }

    /**
     * Sélection d'un fils du noeud selectionne dans l'arbre de navigation.
     *
     * @param context le contexte applicatif
     * @param childIndex index du fils a selectionner
     */
    public void gotoChildNode(JAXXContext context, int childIndex) {

        NavigationTreeNode node = getSelectedNode(context);

        if (node == null) {
            // pas de noeud selectionne
            throw new NullPointerException("no selected node in context");
        }
        node = node.getChildAt(childIndex);

        selectNode(context, node);
    }

    /**
     * Demande une opération de repaint sur un noeud de l'arbre de navigation.
     *
     * Note: La descendance du noeud n'est pas repainte.
     *
     * @param context le contexte applicatif
     * @param node le noeud à repaindre
     */
    public void repaintNode(JAXXContext context, NavigationTreeNode node) {
        repaintNode(context, node, false);
    }

    /**
     * Demande une opération de repaint sur un noeud de l'arbre de navigation.
     *
     * Note: La descendance du noeud est repainte si le paramètre
     * deep est à true.
     *
     * @param context le contexte applicatif
     * @param node le noeud à repaindre
     * @param deep un flag pour activer la repainte de la descendance du noeud
     */
    public void repaintNode(JAXXContext context, NavigationTreeNode node,
                            boolean deep) {
        NavigationModel navigationModel = getSafeModel(context);
        if (log.isDebugEnabled()) {
            log.debug(node);
        }
        navigationModel.nodeChanged(node);
        if (deep) {
            // repaint childs nodes
            //todo we should only repaint necessary nodes ?
            Enumeration e = node.children();
            while (e.hasMoreElements()) {
                NavigationTreeNode child = (NavigationTreeNode) e.nextElement();
                repaintNode(context, child, true);
            }
        }
    }

    /**
     * @deprecated please use {@link #getSafeModel(JAXXContext)}, will be
     *             remove soon
     * @param context where to find
     * @return the tree model
     * @throws NullPointerException if model is null
     */
    @Deprecated
    public NavigationTreeModel getSafeTreeModel(JAXXContext context)
            throws NullPointerException {
        NavigationModel model = getSafeModel(context);
        if (model instanceof NavigationTreeModel){
            return (NavigationTreeModel) model;
        }
        return null;
    }

    public NavigationModel getSafeModel(JAXXContext context)
            throws NullPointerException {
        NavigationModel model = getModel(context);
        if (model == null) {
            throw new NullPointerException("could not find tree model " +
                    "with key " + getModelContextEntry() + " in context " +
                    context);
        }
        return model;
    }

    public JTree getSafeTree(JAXXContext context) throws NullPointerException {
        JTree tree = getTree(context);
        if (tree == null) {
            throw new NullPointerException("could not find tree with key " +
                    getTreeContextEntry() + " in context " + context);
        }
        return tree;
    }

    public JXTreeTable getSafeTreeTable(JAXXContext context)
            throws NullPointerException {
        JXTreeTable treeTable = getTreeTable(context);
        if (treeTable == null) {
            throw new NullPointerException("could not find tree with key " +
                    getTreeTableContextEntry() + " in context " + context);
        }
        return treeTable;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy