📄 elementtreepanel.java
字号:
/**
* @return TreeModel implementation used to represent the elements.
*/
public DefaultTreeModel getTreeModel() {
return treeModel;
}
/**
* Updates the tree based on the event type. This will invoke either
* updateTree with the root element, or handleChange.
*/
protected void updateTree(DocumentEvent event) {
updatingSelection = true;
try {
TreeModel model = getTreeModel();
Object root = model.getRoot();
for(int counter = model.getChildCount(root) - 1; counter >= 0;
counter--) {
updateTree(event, (Element)model.getChild(root, counter));
}
}
finally {
updatingSelection = false;
}
}
/**
* Creates TreeModelEvents based on the DocumentEvent and messages
* the treemodel. This recursively invokes this method with children
* elements.
* @param event indicates what elements in the tree hierarchy have
* changed.
* @param element Current element to check for changes against.
*/
protected void updateTree(DocumentEvent event, Element element) {
DocumentEvent.ElementChange ec = event.getChange(element);
if (ec != null) {
Element[] removed = ec.getChildrenRemoved();
Element[] added = ec.getChildrenAdded();
int startIndex = ec.getIndex();
// Check for removed.
if(removed != null && removed.length > 0) {
int[] indices = new int[removed.length];
for(int counter = 0; counter < removed.length; counter++) {
indices[counter] = startIndex + counter;
}
getTreeModel().nodesWereRemoved((TreeNode)element, indices,
removed);
}
// check for added
if(added != null && added.length > 0) {
int[] indices = new int[added.length];
for(int counter = 0; counter < added.length; counter++) {
indices[counter] = startIndex + counter;
}
getTreeModel().nodesWereInserted((TreeNode)element, indices);
}
}
if(!element.isLeaf()) {
int startIndex = element.getElementIndex
(event.getOffset());
int elementCount = element.getElementCount();
int endIndex = Math.min(elementCount - 1,
element.getElementIndex
(event.getOffset() + event.getLength()));
if(startIndex > 0 && startIndex < elementCount &&
element.getElement(startIndex).getStartOffset() ==
event.getOffset()) {
// Force checking the previous element.
startIndex--;
}
if(startIndex != -1 && endIndex != -1) {
for(int counter = startIndex; counter <= endIndex; counter++) {
updateTree(event, element.getElement(counter));
}
}
}
else {
// Element is a leaf, assume it changed
getTreeModel().nodeChanged((TreeNode)element);
}
}
/**
* Returns a TreePath to the element at <code>position</code>.
*/
protected TreePath getPathForIndex(int position, Object root,
Element rootElement) {
TreePath path = new TreePath(root);
Element child = rootElement.getElement
(rootElement.getElementIndex(position));
path = path.pathByAddingChild(rootElement);
path = path.pathByAddingChild(child);
while(!child.isLeaf()) {
child = child.getElement(child.getElementIndex(position));
path = path.pathByAddingChild(child);
}
return path;
}
/**
* ElementTreeModel is an implementation of TreeModel to handle displaying
* the Elements from a Document. AbstractDocument.AbstractElement is
* the default implementation used by the swing text package to implement
* Element, and it implements TreeNode. This makes it trivial to create
* a DefaultTreeModel rooted at a particular Element from the Document.
* Unfortunately each Document can have more than one root Element.
* Implying that to display all the root elements as a child of another
* root a fake node has be created. This class creates a fake node as
* the root with the children being the root elements of the Document
* (getRootElements).
* <p>This subclasses DefaultTreeModel. The majority of the TreeModel
* methods have been subclassed, primarily to special case the root.
*/
public static class ElementTreeModel extends DefaultTreeModel {
protected Element[] rootElements;
public ElementTreeModel(Document document) {
super(new DefaultMutableTreeNode("root"), false);
rootElements = new Element[] {
document.getDefaultRootElement()};
}
/**
* Returns the child of <I>parent</I> at index <I>index</I> in
* the parent's child array. <I>parent</I> must be a node
* previously obtained from this data source. This should
* not return null if <i>index</i> is a valid index for
* <i>parent</i> (that is <i>index</i> >= 0 && <i>index</i>
* < getChildCount(<i>parent</i>)).
*
* @param parent a node in the tree, obtained from this data source
* @return the child of <I>parent</I> at index <I>index</I>
*/
public Object getChild(Object parent, int index) {
if(parent == root)
return rootElements[index];
return super.getChild(parent, index);
}
/**
* Returns the number of children of <I>parent</I>. Returns 0
* if the node is a leaf or if it has no children.
* <I>parent</I> must be a node previously obtained from this
* data source.
*
* @param parent a node in the tree, obtained from this data source
* @return the number of children of the node <I>parent</I>
*/
public int getChildCount(Object parent) {
if(parent == root)
return rootElements.length;
return super.getChildCount(parent);
}
/**
* Returns true if <I>node</I> is a leaf. It is possible for
* this method to return false even if <I>node</I> has no
* children. A directory in a filesystem, for example, may
* contain no files; the node representing the directory is
* not a leaf, but it also has no children.
*
* @param node a node in the tree, obtained from this data source
* @return true if <I>node</I> is a leaf
*/
public boolean isLeaf(Object node) {
if(node == root)
return false;
return super.isLeaf(node);
}
/**
* Returns the index of child in parent.
*/
public int getIndexOfChild(Object parent, Object child) {
if(parent == root) {
for(int counter = rootElements.length - 1; counter >= 0;
counter--) {
if(rootElements[counter] == child)
return counter;
}
return -1;
}
return super.getIndexOfChild(parent, child);
}
/**
* Invoke this method after you've changed how node is to be
* represented in the tree.
*/
public void nodeChanged(TreeNode node) {
if(listenerList != null && node != null) {
TreeNode parent = node.getParent();
if(parent == null && node != root) {
parent = root;
}
if(parent != null) {
int anIndex = getIndexOfChild(parent, node);
if(anIndex != -1) {
int[] cIndexs = new int[1];
cIndexs[0] = anIndex;
nodesChanged(parent, cIndexs);
}
}
}
}
/**
* Returns the path to a particluar node. This is recursive.
*/
protected TreeNode[] getPathToRoot(TreeNode aNode, int depth) {
TreeNode[] retNodes;
/* Check for null, in case someone passed in a null node, or
they passed in an element that isn't rooted at root. */
if(aNode == null) {
if(depth == 0)
return null;
else
retNodes = new TreeNode[depth];
}
else {
depth++;
if(aNode == root)
retNodes = new TreeNode[depth];
else {
TreeNode parent = aNode.getParent();
if(parent == null)
parent = root;
retNodes = getPathToRoot(parent, depth);
}
retNodes[retNodes.length - depth] = aNode;
}
return retNodes;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -