/* * The Unified Mapping Platform (JUMP) is an extensible, interactive GUI * for visualizing and manipulating spatial features with geometry and attributes. * * Copyright (C) 2003 Vivid Solutions * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * 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 Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * For more information, contact: * * Vivid Solutions * Suite #1A * 2328 Government Street * Victoria BC V8T 5G5 * Canada * * (250)385-6040 * www.vividsolutions.com */ package com.vividsolutions.jump.workbench.ui; import com.vividsolutions.jts.util.Assert; import com.vividsolutions.jump.util.Block; import com.vividsolutions.jump.util.StringUtil; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Stack; import javax.swing.ImageIcon; import javax.swing.JTree; import javax.swing.event.TreeModelEvent; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; public class TreeUtil { public static TreeCellRenderer createSimpleTreeCellRenderer(ImageIcon icon) { return createSimpleTreeCellRenderer(null, icon, new JTree().getFont()); } /** * @param text null to get the text by calling #toString on the value */ public static TreeCellRenderer createSimpleTreeCellRenderer( final String text, final ImageIcon icon, final Font font) { return new DefaultTreeCellRenderer() { { setOpenIcon(icon); setClosedIcon(icon); setLeafIcon(icon); //Transparent. [Jon Aquino] setBackgroundNonSelectionColor(new Color(0, 0, 0, 0)); } public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { Component component = super.getTreeCellRendererComponent(tree, (text == null) ? value : text, sel, expanded, leaf, row, hasFocus); component.setFont(font); return component; } }; } public static void visit(TreeModel model, Visitor visitor) { Stack path = new Stack(); path.push(model.getRoot()); visit(model, path, visitor); } /** * Visit the path and all subpaths. */ public static void visit(TreeModel model, TreePath path, Visitor visitor) { Stack stack = new Stack(); stack.addAll(Arrays.asList(path.getPath())); visit(model, stack, visitor); } private static void visit(TreeModel model, Stack path, Visitor visitor) { visitor.visit(path); for (int i = 0; i < model.getChildCount(path.peek()); i++) { path.push(model.getChild(path.peek(), i)); visit(model, path, visitor); path.pop(); } } public static TreeModelEvent createTreeModelEvent(final Object source, final Object node, final TreeModel model) { TreePath path = findTreePath(node, model); Assert.isTrue(path != null, "Cannot find node in TreeModel: " + node + "\n" + dump(model)); TreePath parentPath = path.getParentPath(); return new TreeModelEvent(source, parentPath, new int[] { model.getIndexOfChild(parentPath.getLastPathComponent(), node) }, new Object[] { node }); } public static String dump(TreeModel model) { final StringBuffer result = new StringBuffer(); visit(model, new Visitor() { public void visit(Stack path) { result.append((StringUtil.repeat(' ', path.size() * 2) + path.lastElement() + "\n")); } }); return result.toString(); } /** * @return null if the node is not in the tree model */ public static TreePath findTreePath(final Object node, final TreeModel model) { final TreePath[] treePath = new TreePath[] { null }; visit(model, new Visitor() { public void visit(Stack path) { if (path.peek() != node) { return; } treePath[0] = new TreePath(path.toArray()); } }); return treePath[0]; } public static boolean contains(TreeModel model, final Object node) { final boolean[] result = new boolean[] { false }; visit(model, new Visitor() { public void visit(Stack path) { if (path.peek() == node) { result[0] = true; } } }); return result[0]; } public static List lastPathComponents(TreePath[] paths) { ArrayList lastPathComponents = new ArrayList(); for (int i = 0; i < paths.length; i++) { lastPathComponents.add(paths[i].getLastPathComponent()); } return lastPathComponents; } public static void expandAll(final JTree tree, TreePath path) { expand(tree, path, new Block() { public Object yield(Object node) { return Boolean.TRUE; } }); } public static void expand(final JTree tree, TreePath path, final Block expandNodeCondition) { visit(tree.getModel(), path, new Visitor() { public void visit(Stack path) { if (!((Boolean)expandNodeCondition.yield(path.peek())).booleanValue()) { return; } tree.expandPath(findTreePath(path.peek(), tree.getModel())); } }); } public static Collection nodes(TreePath path, TreeModel model) { final ArrayList nodes = new ArrayList(); visit(model, path, new Visitor() { public void visit(Stack path) { nodes.add(path.peek()); } }); return nodes; } public static interface Visitor { public void visit(Stack path); } }