📄 automatedtreenode.java
字号:
/*
* Created on 20/6/2004
*
* Copyright (C) 2004 Denis Krukovsky. All rights reserved.
* ====================================================================
* The Software License (based on Apache Software License, Version 1.1)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by
* Denis Krukovsky (dkrukovsky at yahoo.com)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "dot useful" and "Denis Krukovsky" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please
* contact dkrukovsky at yahoo.com.
*
* 5. Products derived from this software may not be called "useful",
* nor may "useful" appear in their name, without prior written
* permission of Denis Krukovsky.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*/
package org.dotuseful.ui.tree;
import javax.swing.event.EventListenerList;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.MutableTreeNode;
/**
* AutomatedTreeNode extends DefaultMutableTreeNode adding support for automatic
* notification of node changes. AutomatedTreeNodes are used with
* AutomatedTreeModel. In this model each node considered as a little tree which
* can fire TreeModel events about its changes. Each parent node registers
* itself as a listener of its child nodes events and transfers events to its
* own listeners (which is its parent) up to the root node. You can use
* AutomatedTreeModel which automatically handles events and fires them as usual
* TreeModel.
* <p>
* A sample of code that uses DefaultTreeModel and DefaultTreeNodes <code>
* setUserObject( event.getObject() );
* //getting a tree model from somewhere
* DefaultTreeModel model = ( DefaultTreeModel ) titleTree.getModel();
* model.nodeChanged( node );
* </code>
* <p>
* A sample of code that uses AutomatedTreeModel and AutomatedTreeNodes <code>
* setUserObject( event.getObject() );
* //Everything else automated
* </code>
* <b>This is not a thread safe class. </b> If you intend to use an
* AutomatedTreeNode (or a tree of TreeNodes) in more than one thread, you need
* to do your own synchronizing. A good convention to adopt is synchronizing on
* the root node of a tree.
* <p>
*
* @author dkrukovsky
*/
public class AutomatedTreeNode extends DefaultMutableTreeNode implements
TreeModelListener {
/** Listeners. */
protected EventListenerList listenerList = new EventListenerList();
/**
* Creates an AutomatedTreeNode that has no parent and no children, but
* which allows children.
*/
public AutomatedTreeNode() {
}
/**
* Creates an AutomatedTreeNode node with no parent, no children, but which
* allows children, and initializes it with the specified user object.
*
* @param userObject
* an Object provided by the user that constitutes the node's
* data
*/
public AutomatedTreeNode(Object userObject) {
super(userObject);
}
/**
* Creates an AutomatedTreeNode with no parent, no children, initialized
* with the specified user object, and that allows children only if
* specified.
*
* @param userObject
* an Object provided by the user that constitutes the node's
* data
* @param allowsChildren
* if true, the node is allowed to have child nodes -- otherwise,
* it is always a leaf node
*/
public AutomatedTreeNode(Object userObject, boolean allowsChildren) {
super(userObject, allowsChildren);
}
/**
* Removes <code>newChild</code> from its present parent (if it has a
* parent), sets the child's parent to this node, adds the child to this
* node's child array at index <code>childIndex</code>, fires a
* <code>nodesWereInserted</code> event, and then adds itself as a
* <code>TreeModelListener</code> to <code>newChild</code>.
* <code>newChild</code> must not be null and must not be an ancestor of
* this node.
*
* @param newChild
* the MutableTreeNode to insert under this node
* @param childIndex
* the index in this node's child array where this node is to be
* inserted
* @exception ArrayIndexOutOfBoundsException
* if <code>childIndex</code> is out of bounds
* @exception IllegalArgumentException
* if <code>newChild</code> is null or is an ancestor of
* this node
* @exception IllegalStateException
* if this node does not allow children
* @see #isNodeDescendant
*/
/**
* Removes <code>newChild</code> from its present parent (if it has a
* parent), sets the child's parent to this node, adds the child to this
* node's child array at index <code>childIndex</code>, fires a
* <code>nodesWereInserted</code> event, and then adds itself as a
* <code>TreeModelListener</code> to <code>newChild</code>.
* <code>newChild</code> must not be null and must not be an ancestor of
* this node.
*
* @param newChild
* the MutableTreeNode to insert under this node
* @param childIndex
* the index in this node's child array where this node is to be
* inserted
* @exception ArrayIndexOutOfBoundsException
* if <code>childIndex</code> is out of bounds
* @exception IllegalArgumentException
* if <code>newChild</code> is null or is an ancestor of
* this node
* @exception IllegalStateException
* if this node does not allow children
* @see #isNodeDescendant
*/
public void insert(final MutableTreeNode newChild, final int childIndex) {
super.insert(newChild, childIndex);
int[] newIndexs = new int[1];
newIndexs[0] = childIndex;
nodesWereInserted(newIndexs);
((AutomatedTreeNode) newChild).addTreeModelListener(this);
}
/**
* Removes the child at the specified index from this node's children and
* sets that node's parent to null. The child node to remove must be a
* <code>MutableTreeNode</code>.
*
* @param childIndex
* the index in this node's child array of the child to remove
* @exception ArrayIndexOutOfBoundsException
* if <code>childIndex</code> is out of bounds
*/
public void remove(final int childIndex) {
Object[] removedArray = new Object[1];
AutomatedTreeNode node = (AutomatedTreeNode) getChildAt(childIndex);
node.removeTreeModelListener(this);
removedArray[0] = node;
super.remove(childIndex);
nodesWereRemoved(new int[] { childIndex }, removedArray);
}
/**
* Sets the user object for this node to <code>userObject</code>.
*
* @param userObject
* the Object that constitutes this node's user-specified data
* @see #toString
*/
public void setUserObject(Object userObject) {
super.setUserObject(userObject);
nodeChanged();
}
/**
* <p>
* Invoked after a node (or a set of siblings) has changed in some way. The
* node(s) have not changed locations in the tree or altered their children
* arrays, but other attributes have changed and may affect presentation.
* Example: the name of a file has changed, but it is in the same location
* in the file system.
* </p>
*/
public void treeNodesChanged(TreeModelEvent e) {
fireTreeNodesChanged(e.getSource(), e.getPath(), e.getChildIndices(), e
.getChildren());
}
/**
* <p>
* Invoked after nodes have been inserted into the tree.
* </p>
*/
public void treeNodesInserted(TreeModelEvent e) {
fireTreeNodesInserted(e.getSource(), e.getPath(), e.getChildIndices(),
e.getChildren());
}
/**
* <p>
* Invoked after nodes have been removed from the tree. Note that if a
* subtree is removed from the tree, this method may only be invoked once
* for the root of the removed subtree, not once for each individual set of
* siblings removed.
* </p>
*/
public void treeNodesRemoved(TreeModelEvent e) {
fireTreeNodesRemoved(e.getSource(), e.getPath(), e.getChildIndices(), e
.getChildren());
}
/**
* <p>
* Invoked after the tree has drastically changed structure from a given
* node down. If the path returned by e.getPath() is of length one and the
* first element does not identify the current root node the first element
* should become the new root of the tree.
* <p>
*/
public void treeStructureChanged(TreeModelEvent e) {
fireTreeStructureChanged(e.getSource(), e.getPath(), e
.getChildIndices(), e.getChildren());
}
/**
* Invoke this method after the node changed how it is to be represented in
* the tree.
*/
protected void nodeChanged() {
if (listenerList != null) {
AutomatedTreeNode parent = (AutomatedTreeNode) getParent();
if (parent != null) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -