📄 elementtreepanel.java
字号:
/*
* @(#)ElementTreePanel.java 1.6 98/08/26
*
* Copyright 1998 by Sun Microsystems, Inc.,
* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of Sun Microsystems, Inc. ("Confidential Information"). You
* shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with Sun.
*/
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.tree.*;
import javax.swing.undo.*;
import java.awt.*;
import java.util.*;
/**
* Displays a tree showing all the elements in a text Document. Selecting
* a node will result in reseting the selection of the JTextComponent.
* This also becomes a CaretListener to know when the selection has changed
* in the text to update the selected item in the tree.
*
* @author Scott Violet
* @version 1.6 08/26/98
*/
public class ElementTreePanel extends JPanel implements CaretListener, DocumentListener, TreeSelectionListener {
/** Tree showing the documents element structure. */
protected JTree tree;
/** Text component showing elemenst for. */
protected JTextComponent editor;
/** Model for the tree. */
protected ElementTreeModel treeModel;
/** Set to true when updatin the selection. */
protected boolean updatingSelection;
public ElementTreePanel(JTextComponent editor) {
this.editor = editor;
Document document = editor.getDocument();
// Create the tree.
treeModel = new ElementTreeModel(document);
tree = new JTree(treeModel) {
public String convertValueToText(Object value, boolean selected,
boolean expanded, boolean leaf,
int row, boolean hasFocus) {
// Should only happen for the root
if(!(value instanceof Element))
return value.toString();
Element e = (Element)value;
AttributeSet as = e.getAttributes().copyAttributes();
String asString;
if(as != null) {
StringBuffer retBuffer = new StringBuffer("[");
Enumeration names = as.getAttributeNames();
while(names.hasMoreElements()) {
Object nextName = names.nextElement();
if(nextName != StyleConstants.ResolveAttribute) {
retBuffer.append(" ");
retBuffer.append(nextName);
retBuffer.append("=");
retBuffer.append(as.getAttribute(nextName));
}
}
retBuffer.append(" ]");
asString = retBuffer.toString();
}
else
asString = "[ ]";
if(e.isLeaf())
return e.getName() + " [" + e.getStartOffset() +
", " + e.getEndOffset() +"] Attributes: " + asString;
return e.getName() + " [" + e.getStartOffset() +
", " + e.getEndOffset() + "] Attributes: " +
asString;
}
};
tree.addTreeSelectionListener(this);
// Don't show the root, it is fake.
tree.setRootVisible(false);
// Since the display value of every node after the insertion point
// changes every time the text changes and we don't generate a change
// event for all those nodes the display value can become off.
// This can be seen as '...' instead of the complete string value.
// This is a temporary workaround, increase the needed size by 15,
// hoping that will be enough.
tree.setCellRenderer(new DefaultTreeCellRenderer() {
public Dimension getPreferredSize() {
Dimension retValue = super.getPreferredSize();
if(retValue != null)
retValue.width += 15;
return retValue;
}
});
// become a listener on the document to update the tree.
document.addDocumentListener(this);
// Become a CaretListener
editor.addCaretListener(this);
// configure the panel and frame containing it.
setLayout(new BorderLayout());
add(new JScrollPane(tree), BorderLayout.CENTER);
// Add a label above tree to describe what is being shown
JLabel label = new JLabel("Elements that make up the current document", SwingConstants.CENTER);
label.setFont(new Font("Dialog", Font.BOLD, 14));
add(label, BorderLayout.NORTH);
setPreferredSize(new Dimension(250, 250));
}
// DocumentListener
/**
* Gives notification that there was an insert into the document. The
* given range bounds the freshly inserted region.
*
* @param e the document event
*/
public void insertUpdate(DocumentEvent e) {
updateTree(e);
}
/**
* Gives notification that a portion of the document has been
* removed. The range is given in terms of what the view last
* saw (that is, before updating sticky positions).
*
* @param e the document event
*/
public void removeUpdate(DocumentEvent e) {
updateTree(e);
}
/**
* Gives notification that an attribute or set of attributes changed.
*
* @param e the document event
*/
public void changedUpdate(DocumentEvent e) {
updateTree(e);
}
// CaretListener
/**
* Messaged when the selection in the editor has changed. Will update
* the selection in the tree.
*/
public void caretUpdate(CaretEvent e) {
if(!updatingSelection) {
JTextComponent editor = getEditor();
int selBegin = Math.min(e.getDot(), e.getMark());
int end = Math.max(e.getDot(), e.getMark());
Vector paths = new Vector();
TreeModel model = getTreeModel();
Object root = model.getRoot();
int rootCount = model.getChildCount(root);
// Build an array of all the paths to all the character elements
// in the selection.
for(int counter = 0; counter < rootCount; counter++) {
int start = selBegin;
while(start <= end) {
TreePath path = getPathForIndex(start, root,
(Element)model.getChild(root, counter));
Element charElement = (Element)path.
getLastPathComponent();
paths.addElement(path);
if(start >= charElement.getEndOffset())
start++;
else
start = charElement.getEndOffset();
}
}
// If a path was found, select it (them).
int numPaths = paths.size();
if(numPaths > 0) {
TreePath[] pathArray = new TreePath[numPaths];
paths.copyInto(pathArray);
updatingSelection = true;
try {
getTree().setSelectionPaths(pathArray);
getTree().scrollPathToVisible(pathArray[0]);
}
finally {
updatingSelection = false;
}
}
}
}
// TreeSelectionListener
/**
* Called whenever the value of the selection changes.
* @param e the event that characterizes the change.
*/
public void valueChanged(TreeSelectionEvent e) {
JTree tree = getTree();
if(!updatingSelection && tree.getSelectionCount() == 1) {
TreePath selPath = tree.getSelectionPath();
Object lastPathComponent = selPath.getLastPathComponent();
if(!(lastPathComponent instanceof DefaultMutableTreeNode)) {
Element selElement = (Element)lastPathComponent;
updatingSelection = true;
try {
getEditor().select(selElement.getStartOffset(),
selElement.getEndOffset());
}
finally {
updatingSelection = false;
}
}
}
}
// Local methods
/**
* @return tree showing elements.
*/
protected JTree getTree() {
return tree;
}
/**
* @return JTextComponent showing elements for.
*/
protected JTextComponent getEditor() {
return editor;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -