|
Java example source code file (ElementTreePanel.java)
The ElementTreePanel.java Java example source code/* * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - 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. * * - Neither the name of Oracle nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS 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 THE COPYRIGHT OWNER OR * 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. */ /* * This source code is provided to illustrate the usage of a given feature * or technique and has been deliberately simplified. Additional steps * required for a production-quality application, such as security checks, * input validation and proper error handling, might not be present in * this sample code. */ import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Font; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.*; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.SwingConstants; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.text.AttributeSet; import javax.swing.text.Document; import javax.swing.text.Element; import javax.swing.text.JTextComponent; import javax.swing.text.StyleConstants; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; /** * 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 */ @SuppressWarnings("serial") public class ElementTreePanel extends JPanel implements CaretListener, DocumentListener, PropertyChangeListener, 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; @SuppressWarnings("LeakingThisInConstructor") public ElementTreePanel(JTextComponent editor) { this.editor = editor; Document document = editor.getDocument(); // Create the tree. treeModel = new ElementTreeModel(document); tree = new JTree(treeModel) { @Override 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) { StringBuilder retBuffer = new StringBuilder("["); 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); tree.setDragEnabled(true); // 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() { @Override 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 PropertyChangeListener to know when the Document has // changed. editor.addPropertyChangeListener(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(400, 400)); } /** * Resets the JTextComponent to <code>editor. This will update * the tree accordingly. */ public void setEditor(JTextComponent editor) { if (this.editor == editor) { return; } if (this.editor != null) { Document oldDoc = this.editor.getDocument(); oldDoc.removeDocumentListener(this); this.editor.removePropertyChangeListener(this); this.editor.removeCaretListener(this); } this.editor = editor; if (editor == null) { treeModel = null; tree.setModel(null); } else { Document newDoc = editor.getDocument(); newDoc.addDocumentListener(this); editor.addPropertyChangeListener(this); editor.addCaretListener(this); treeModel = new ElementTreeModel(newDoc); tree.setModel(treeModel); } } // PropertyChangeListener /** * Invoked when a property changes. We are only interested in when the * Document changes to reset the DocumentListener. */ public void propertyChange(PropertyChangeEvent e) { if (e.getSource() == getEditor() && e.getPropertyName().equals( "document")) { Document oldDoc = (Document) e.getOldValue(); Document newDoc = (Document) e.getNewValue(); // Reset the DocumentListener oldDoc.removeDocumentListener(this); newDoc.addDocumentListener(this); // Recreate the TreeModel. treeModel = new ElementTreeModel(newDoc); tree.setModel(treeModel); } } // 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) { int selBegin = Math.min(e.getDot(), e.getMark()); int end = Math.max(e.getDot(), e.getMark()); List<TreePath> paths = new ArrayList Other Java examples (source code examples)Here is a short list of links related to this Java ElementTreePanel.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.