/** * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.brixcms.web.tree; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.apache.wicket.extensions.markup.html.tree.AbstractTree; /** * AbstractTreeModel that delegates the tree structure to {@link TreeNode}. It also contains convenience methods that * inform the tree component that the tree structure has been changed. * * @author Matej Knopp */ public abstract class AbstractTreeModel implements Serializable, TreeModel { private List<TreeModelListener> listeners = new ArrayList<TreeModelListener>(0); /** * Returns the root node of this tree. This is the only mandatory method to be implemented for custom tree models. */ public abstract javax.swing.tree.TreeNode getRoot(); public Object getChild(Object parent, int index) { List<?> children = ((TreeNode) parent).getChildren(); return children != null ? children.get(index) : null; } public int getChildCount(Object parent) { List<?> children = ((TreeNode) parent).getChildren(); return children != null ? children.size() : 0; } public boolean isLeaf(Object node) { return ((TreeNode) node).isLeaf(); } public void valueForPathChanged(TreePath path, Object newValue) { } public int getIndexOfChild(Object parent, Object child) { List<?> children = ((TreeNode) parent).getChildren(); return children != null ? children.indexOf(child) : -1; } public void addTreeModelListener(TreeModelListener l) { listeners.add(l); } public void removeTreeModelListener(TreeModelListener l) { listeners.remove(l); } /** * Notifies the tree that the given node has been changed while it's children remained unchanged. * * @param tree * @param node */ public void nodeChanged(AbstractTree tree, TreeNode node) { TreeNode parent = (TreeNode) getParent(tree, node); if (parent != null) { int index = parent.getChildren().indexOf(node); if (index != -1) { TreeModelEvent e = new TreeModelEvent(this, pathFromNode(tree, parent), new int[]{index}, new Object[]{node}); for (TreeModelListener l : listeners) { l.treeNodesChanged(e); } } } } private TreePath pathFromNode(AbstractTree tree, TreeNode node) { List<TreeNode> l = new ArrayList<TreeNode>(); for (TreeNode n = node; n != null; n = (TreeNode) getParent(tree, n)) { l.add(0, n); } return new TreePath(l.toArray(new TreeNode[l.size()])); } public Object getParent(AbstractTree tree, Object node) { return tree.getParentNode(node); } /** * Notifies the tree that the children of given node have been changed. * * @param tree * @param node */ public void nodeChildrenChanged(AbstractTree tree, TreeNode node) { TreeModelEvent event = new TreeModelEvent(this, pathFromNode(tree, node)); for (TreeModelListener l : listeners) { l.treeStructureChanged(event); } } /** * Notifies the tree that the given node will be removed. This method must be called <b>before</b> the node is actually * deleted. * * @param tree * @param node */ public void nodeDeleted(AbstractTree tree, TreeNode node) { TreeNode parent = (TreeNode) getParent(tree, node); if (parent != null) { int index = parent.getChildren().indexOf(node); if (index != -1) { TreeModelEvent e = new TreeModelEvent(this, pathFromNode(tree, parent), new int[]{index}, new Object[]{node}); for (TreeModelListener l : listeners) { l.treeNodesRemoved(e); } } } } /** * Notifies the tree that the given node has been added. * * @param tree * @param node */ public void nodeInserted(AbstractTree tree, TreeNode parent, TreeNode node) { int index = parent.getChildren().indexOf(node); if (index != -1) { TreeModelEvent e = new TreeModelEvent(this, pathFromNode(tree, parent), new int[]{index}, new Object[]{node}); for (TreeModelListener l : listeners) { l.treeNodesInserted(e); } } } }