/* * Copyright (C) 2010 Markus Echterhoff <tam@edu.uni-klu.ac.at> * * This file is part of EvoPaint. * * EvoPaint 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 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 Public License for more details. * * You should have received a copy of the GNU General Public License * along with EvoPaint. If not, see <http://www.gnu.org/licenses/>. */ package evopaint.gui.rulesetmanager; import evopaint.pixel.rulebased.RuleSet; import evopaint.pixel.rulebased.RuleSetCollection; import evopaint.pixel.rulebased.interfaces.INamed; import evopaint.util.CollectionNode; import java.awt.Component; import java.awt.event.MouseListener; import java.util.Enumeration; import java.util.List; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; /** * * @author Markus Echterhoff <tam@edu.uni-klu.ac.at> */ public class JRuleSetTree extends JTree { // implements TreeModelListener { public JRuleSetTree(DefaultTreeModel model, MouseListener mouseListener) { setRootVisible(false); // setExpandsSelectedPaths(true); // broken POS (just does not work) setShowsRootHandles(true); setToggleClickCount(1); getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); setCellRenderer(new RuleSetTreeCellRenderer()); setModel(model); // model.addTreeModelListener(this); // broken POS2 (will do a lot of // stuff, eg. not expand, not scroll, but when you reload the model // before you call the mentioned methods, it will cause empty lines and // even nullpointer exceptions in the UI addMouseListener(mouseListener); } // workaround for broken POS2 public void updateVisibleInsert(DefaultMutableTreeNode node) { TreePath selectionPath = new TreePath(node.getPath()); setSelectionPath(selectionPath); expandPath(selectionPath); // workaround for broken POS1 scrollPathToVisible(selectionPath); } // workaround for broken POS2 public void updateVisibleRemove(DefaultMutableTreeNode parentNode, int removedChildIndex) { DefaultMutableTreeNode selectedNode = null; if (parentNode.getChildCount() > 0) { // have other children to select? if (removedChildIndex < parentNode.getChildCount()) { // have childdren after removed one? selectedNode = (DefaultMutableTreeNode)parentNode.getChildAt(removedChildIndex); } else { selectedNode = (DefaultMutableTreeNode)parentNode.getChildAt(removedChildIndex - 1); } } else { selectedNode = parentNode; } setSelectionPath(new TreePath(selectedNode.getPath())); } public boolean isUniqueSiblingName(TreeNode parentNode, Object original, String name) { Enumeration enumeration = parentNode.children(); assert(enumeration != null); while (enumeration.hasMoreElements()) { DefaultMutableTreeNode node = (DefaultMutableTreeNode)enumeration.nextElement(); INamed namedObject = (INamed)node.getUserObject(); if (original != namedObject && name.equals(namedObject.getName())) { showNameExistsError(); return false; } } return true; } private void showNameExistsError() { JOptionPane.showMessageDialog((JFrame)SwingUtilities.getWindowAncestor(this), "Are you trying to make me crash saving stuff with already existing names?\nThis is not going to happen, baby... not going to happen at all...\nNow go and choose a different name, mkay? We good now.", "I am angry with you!", JOptionPane.ERROR_MESSAGE); } /* code for broken POS2 public void treeNodesChanged(TreeModelEvent e) { } public void treeNodesInserted(TreeModelEvent e) { DefaultMutableTreeNode newNode = (DefaultMutableTreeNode)e.getChildren()[0]; TreePath selectionPath = new TreePath(newNode.getPath()); setSelectionPath(selectionPath); // select the new item (and expand it - setExpandsSelectedPaths(true)) scrollPathToVisible(selectionPath); // make it visible in case we have to scroll } public void treeNodesRemoved(TreeModelEvent e) { int removedAt = e.getChildIndices()[0]; DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)e.getTreePath().getLastPathComponent(); DefaultMutableTreeNode selectedNode = null; if (parentNode.getChildCount() > 0) { // have other children to select? if (removedAt < parentNode.getChildCount()) { // have childdren after removed one? selectedNode = (DefaultMutableTreeNode)parentNode.getChildAt(removedAt); } else { selectedNode = (DefaultMutableTreeNode)parentNode.getChildAt(removedAt - 1); } } else { selectedNode = parentNode; } setSelectionPath(new TreePath(selectedNode.getPath())); } public void treeStructureChanged(TreeModelEvent e) { } */ private class RuleSetTreeCellRenderer extends DefaultTreeCellRenderer { @Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { Object userObject = ((DefaultMutableTreeNode)value).getUserObject(); if (userObject instanceof RuleSet) { return super.getTreeCellRendererComponent(tree, new DefaultMutableTreeNode(((RuleSet)userObject).getName()), sel, expanded, leaf, row, hasFocus); } if (userObject instanceof RuleSetCollection) { return super.getTreeCellRendererComponent(tree, new DefaultMutableTreeNode(((RuleSetCollection)userObject).getName()), sel, expanded, leaf, row, hasFocus); } return super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); } } }