Author: sletellier Date: 2010-03-02 17:21:34 +0100 (Tue, 02 Mar 2010) New Revision: 1753 Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationMultiContentUI.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationMultiTreeHandler.java Modified: trunk/jaxx-demo/src/main/java/jaxx/demo/component/jaxx/navigation/FullNavigationTreeHelper.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeContextHelper.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandler.java trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandlerWithCardLayout.java Log: Adding support of multiSelection in navigation tree Modified: trunk/jaxx-demo/src/main/java/jaxx/demo/component/jaxx/navigation/FullNavigationTreeHelper.java =================================================================== --- trunk/jaxx-demo/src/main/java/jaxx/demo/component/jaxx/navigation/FullNavigationTreeHelper.java 2010-03-01 11:25:30 UTC (rev 1752) +++ trunk/jaxx-demo/src/main/java/jaxx/demo/component/jaxx/navigation/FullNavigationTreeHelper.java 2010-03-02 16:21:34 UTC (rev 1753) @@ -106,7 +106,7 @@ NavigationTreeModel model = builder.getModel(); // save tree model in context - setTreeModel(context, model); + setModel(context, model); return model; } @@ -127,8 +127,8 @@ private static final long serialVersionUID = 1L; @Override - protected NavigationTreeModel getNavigationTreeModel() { - return getSafeTreeModel(getContext()); + protected NavigationModel getNavigationTreeModel() { + return getSafeModel(getContext()); } @Override Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationMultiContentUI.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationMultiContentUI.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationMultiContentUI.java 2010-03-02 16:21:34 UTC (rev 1753) @@ -0,0 +1,53 @@ +/* + * *##% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * ##%* + */ + +package jaxx.runtime.swing.navigation; + +import java.util.List; + +/** + * Contract on a content UI with list of beans. + * + * @author sletellier + * @since 2.0.1 + */ +public interface NavigationMultiContentUI extends NavigationContentUI{ + + /** + * Init the ui just before been opened by the method + * {@link NavigationMultiTreeHandler#openUI(java.awt.Component, + * java.util.List<jaxx.runtime.swing.navigation.NavigationTreeNode>)}. + * + * @param nodes the selected node associated to the ui + * @throws Exception if any pb while opening the content's ui + */ + void openUI(List<NavigationTreeNode> nodes) throws Exception; + + /** + * Clean the ui after been closed by the method + * {@link NavigationTreeHandler#closeUI(java.awt.Component)}. + * + * @param nodes the selected node associated to the ui + * @throws Exception if any pb when closing the content'sui + * @see NavigationTreeHandler#closeUI(java.awt.Component) + */ + void closeUI(List<NavigationTreeNode> nodes) throws Exception; +} Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationMultiTreeHandler.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationMultiTreeHandler.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationMultiTreeHandler.java 2010-03-02 16:21:34 UTC (rev 1753) @@ -0,0 +1,177 @@ +/* + * *##% + * 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 + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * ##%* + */ + +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.JAXXContext; +import jaxx.runtime.JAXXObject; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.event.TreeSelectionEvent; +import javax.swing.tree.TreePath; +import java.awt.Component; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * The handler of a navigation tree. + * + * This is also the selection model to use, since we must check before moving + * from nodes we can not just listen selection model changed, we must control + * it. + * + * @author sletellier + * @since 2.0.1 + */ +public abstract class NavigationMultiTreeHandler extends NavigationTreeHandler { + /** + * Logger + */ + static private final Log log = LogFactory.getLog(NavigationMultiTreeHandler.class); + + + public NavigationMultiTreeHandler(String contextPrefix, JAXXObject context, Strategy strategy) { + super(contextPrefix, context, strategy); + } + + @Override + public void valueChanged(TreeSelectionEvent event) { + TreePath[] paths = getSelectionPaths(); + + // TODO : verifier que la selection n'est pas la même + List<NavigationTreeNode> nodes = new ArrayList<NavigationTreeNode>(); + if (paths == null){ + selectNodeUI(new ArrayList<NavigationTreeNode>()); + return; + } + for(TreePath path : paths){ + NavigationTreeNode node = (NavigationTreeNode) path.getLastPathComponent(); + nodes.add(node); + if (log.isDebugEnabled()){ + log.debug("Adding path : " + path); + log.debug("As node : " + node.getFullPath()); + } + } + selectNodeUI(nodes); + } + + /** + * Ouvre l'ui associée aux noeuds sélectionnés dans l'arbre de navigation. + * + * @param newUI l'ui associé au noeud sélectionné à ouvrir + * @param nodes les node de l'ui a ouvrir + * @throws Exception if any + */ + protected abstract void openUI(Component newUI, List<NavigationTreeNode> nodes) throws Exception; + + /** + * Instancie une nouvelle ui associé à des noeuds de l'arbre de navigation + * + * @param nodes les noeuds associés à l'ui à créer + * @return la nouvelle ui associée au noeud + * @throws Exception if any + */ + protected abstract Component createUI(List<NavigationTreeNode> nodes) throws Exception; + + /** + * @param nodes les noeuds associés à l'ui à retrouver + * @return l'ui associés au nouveau noeud sélectionné + */ + protected abstract Component getUI(List<NavigationTreeNode> nodes); + + protected void selectNodeUI(List<NavigationTreeNode> nodes) { + log.info("select nodes " + nodes); + + try { + List<String> paths = new ArrayList<String>(); + List<Object> beans = new ArrayList<Object>(); + for (NavigationTreeNode node : nodes){ + + String path = node.getFullPath(); + paths.add(path); + + if (log.isTraceEnabled()) { + log.trace(path); + } + // now, we are free to open the ui associated with the selected node in navigation + + // get the bean associated with the node + beans.add(getNavigationTreeModel().getBean(path)); + } + + Component newUI = getUI(nodes); + + // save it in context (must be done before init ui) + 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 (beans != null) { + helper.setSelectedBeans(ctxt, beans); + } + + if (newUI == null) { + + // a new ui instance is required + newUI = createUI(nodes); + } + + // save in context current node context path + helper.setSelectedPaths(ctxt, getPaths(nodes)); + + // save in context current node + helper.setSelectedNodes(ctxt, nodes); + + // 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 NavigationMultiContentUI) { + ((NavigationMultiContentUI) newUI).openUI(nodes); + } + + // set ui in content + openUI(newUI, nodes); + + } catch (Exception e) { + // remove data from context + + // if any error, go back to previvous node + treateError(e); + } + } + + public List<String> getPaths(List<NavigationTreeNode> nodes){ + List<String> result = new ArrayList<String>(); + for (NavigationTreeNode node : nodes){ + result.add(node.getFullPath()); + } + return result; + } + +} Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeContextHelper.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeContextHelper.java 2010-03-01 11:25:30 UTC (rev 1752) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeContextHelper.java 2010-03-02 16:21:34 UTC (rev 1753) @@ -25,8 +25,13 @@ import jaxx.runtime.JAXXContext; import jaxx.runtime.JAXXUtil; import jaxx.runtime.context.JAXXContextEntryDef; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.jdesktop.swingx.JXTreeTable; +import java.util.ArrayList; +import java.util.List; + /** * To help getting and setting navigation tree objects from a {@link JAXXContext}. * <p/> @@ -61,10 +66,15 @@ */ public class NavigationTreeContextHelper { + /** + * Logger + */ + static private final Log log = LogFactory.getLog(NavigationTreeContextHelper.class); + protected final String prefix; - protected JAXXContextEntryDef<String> selectedPathContextEntry; - protected JAXXContextEntryDef<Object> selectedBeanContextEntry; - protected JAXXContextEntryDef<NavigationTreeNode> selectedNodeContextEntry; + protected JAXXContextEntryDef<List<String>> selectedPathsContextEntry; + protected JAXXContextEntryDef<List<Object>> selectedBeansContextEntry; + protected JAXXContextEntryDef<List<NavigationTreeNode>> selectedNodesContextEntry; protected JAXXContextEntryDef<NavigationModel> modelContextEntry; protected JAXXContextEntryDef<NavigationTreeHandler> handlerContextEntry; protected JAXXContextEntryDef<JTree> treeContextEntry; @@ -77,9 +87,9 @@ treeTableContextEntry = JAXXUtil.newContextEntryDef(prefix + "-tree-table", JXTreeTable.class); modelContextEntry = JAXXUtil.newContextEntryDef(prefix + "-model", NavigationModel.class); handlerContextEntry = JAXXUtil.newContextEntryDef(prefix + "-handler", NavigationTreeHandler.class); - selectedBeanContextEntry = JAXXUtil.newContextEntryDef(prefix + "-selected-bean", Object.class); - selectedNodeContextEntry = JAXXUtil.newContextEntryDef(prefix + "-selected-node", NavigationTreeNode.class); - selectedPathContextEntry = JAXXUtil.newContextEntryDef(prefix + "-selected-path", String.class); + selectedBeansContextEntry = JAXXUtil.newListContextEntryDef(prefix + "-selected-beans"); + selectedNodesContextEntry = JAXXUtil.newListContextEntryDef(prefix + "-selected-nodes"); + selectedPathsContextEntry = JAXXUtil.newListContextEntryDef(prefix + "-selected-paths"); // selectedUIContextEntry = JAXXUtil.newContextEntryDef(prefix + "-selected-ui", Component.class); } @@ -121,20 +131,47 @@ } public String getSelectedPath(JAXXContext context) { - String r = getSelectedPathContextEntry().getContextValue(context); - return r; + List<String> values = getSelectedPathContextEntry().getContextValue(context); + if (log.isWarnEnabled()){ + if (values.size() > 1){ + log.warn("More than one values are selected, return first one"); + } + } + return values.get(0); } + public List<String> getSelectedPaths(JAXXContext context) { + return getSelectedPathContextEntry().getContextValue(context); + } + public NavigationTreeNode getSelectedNode(JAXXContext context) { - NavigationTreeNode r = getSelectedNodeContextEntry().getContextValue(context); - return r; + List<NavigationTreeNode> values = getSelectedNodeContextEntry().getContextValue(context); + if (log.isWarnEnabled()){ + if (values.size() > 1){ + log.warn("More than one values are selected, return first one"); + } + } + return values.get(0); } + public List<NavigationTreeNode> getSelectedNodes(JAXXContext context) { + return getSelectedNodeContextEntry().getContextValue(context); + } + public Object getSelectedBean(JAXXContext context) { - Object r = getSelectedBeanContextEntry().getContextValue(context); - return r; + List<Object> values = getSelectedBeanContextEntry().getContextValue(context); + if (log.isWarnEnabled()){ + if (values.size() > 1){ + log.warn("More than one values are selected, return first one"); + } + } + return values.get(0); } + public List<Object> getSelectedBeans(JAXXContext context) { + return getSelectedBeanContextEntry().getContextValue(context); + } + // public Component getSelectedUI(JAXXContext context) { // Component r = getSelectedUIContextEntry().getContextValue(context); // return r; @@ -170,26 +207,56 @@ if (path == null) { getSelectedPathContextEntry().removeContextValue(context); } else { - getSelectedPathContextEntry().setContextValue(context, path); + List<String> selecteds = new ArrayList<String>(); + selecteds.add(path); + getSelectedPathContextEntry().setContextValue(context, selecteds); } } + public void setSelectedPaths(JAXXContext context, List<String> paths) { + if (paths == null || paths.isEmpty()) { + getSelectedPathContextEntry().removeContextValue(context); + } else { + getSelectedPathContextEntry().setContextValue(context, paths); + } + } + public void setSelectedNode(JAXXContext context, NavigationTreeNode node) { if (node == null) { getSelectedNodeContextEntry().removeContextValue(context); } else { - getSelectedNodeContextEntry().setContextValue(context, node); + List<NavigationTreeNode> selecteds = new ArrayList<NavigationTreeNode>(); + selecteds.add(node); + getSelectedNodeContextEntry().setContextValue(context, selecteds); } } + public void setSelectedNodes(JAXXContext context, List<NavigationTreeNode> nodes) { + if (nodes == null || nodes.isEmpty()) { + getSelectedNodeContextEntry().removeContextValue(context); + } else { + getSelectedNodeContextEntry().setContextValue(context, nodes); + } + } + public void setSelectedBean(JAXXContext context, Object bean) { if (bean == null) { getSelectedBeanContextEntry().removeContextValue(context); } else { - getSelectedBeanContextEntry().setContextValue(context, bean); + List<Object> selecteds = new ArrayList<Object>(); + selecteds.add(bean); + getSelectedBeanContextEntry().setContextValue(context, selecteds); } } + public void setSelectedBeans(JAXXContext context, List<Object> beans) { + if (beans == null || beans.isEmpty()) { + getSelectedBeanContextEntry().removeContextValue(context); + } else { + getSelectedBeanContextEntry().setContextValue(context, beans); + } + } + // public void setSelectedUI(JAXXContext context, Component ui) { // if (ui == null) { // getSelectedUIContextEntry().removeContextValue(context); @@ -206,16 +273,16 @@ return handlerContextEntry; } - protected JAXXContextEntryDef<Object> getSelectedBeanContextEntry() { - return selectedBeanContextEntry; + protected JAXXContextEntryDef<List<Object>> getSelectedBeanContextEntry() { + return selectedBeansContextEntry; } - protected JAXXContextEntryDef<NavigationTreeNode> getSelectedNodeContextEntry() { - return selectedNodeContextEntry; + protected JAXXContextEntryDef<List<NavigationTreeNode>> getSelectedNodeContextEntry() { + return selectedNodesContextEntry; } - protected JAXXContextEntryDef<String> getSelectedPathContextEntry() { - return selectedPathContextEntry; + protected JAXXContextEntryDef<List<String>> getSelectedPathContextEntry() { + return selectedPathsContextEntry; } protected JAXXContextEntryDef<JTree> getTreeContextEntry() { Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandler.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandler.java 2010-03-01 11:25:30 UTC (rev 1752) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandler.java 2010-03-02 16:21:34 UTC (rev 1753) @@ -208,6 +208,42 @@ 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 path " + paths); + } + // ok can safely select the new path + super.setSelectionPaths(paths); + } + protected void selectNodeUI(NavigationTreeNode node) { try { Modified: trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandlerWithCardLayout.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandlerWithCardLayout.java 2010-03-01 11:25:30 UTC (rev 1752) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandlerWithCardLayout.java 2010-03-02 16:21:34 UTC (rev 1753) @@ -28,6 +28,7 @@ import javax.swing.JPanel; import java.awt.Component; +import java.util.List; /** * Simple {@link NavigationTreeHandler} implementation with a {@link CardLayout2} to manage components to