📄 basictreeui.java
字号:
/* * @(#)BasicTreeUI.java 1.156 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package javax.swing.plaf.basic;import javax.swing.*;import javax.swing.event.*;import java.awt.*;import java.awt.event.*;import java.awt.datatransfer.*;import java.awt.dnd.*;import java.beans.*;import java.io.*;import java.util.Enumeration;import java.util.Hashtable;import java.util.TooManyListenersException;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import javax.swing.plaf.ActionMapUIResource;import javax.swing.plaf.ComponentUI;import javax.swing.plaf.UIResource;import javax.swing.plaf.TreeUI;import javax.swing.tree.*;import javax.swing.text.Position;/** * The basic L&F for a hierarchical data structure. * <p> * * @version 1.156 01/23/03 * @author Scott Violet */public class BasicTreeUI extends TreeUI{ static private final Insets EMPTY_INSETS = new Insets(0, 0, 0, 0); transient protected Icon collapsedIcon; transient protected Icon expandedIcon; /** * Color used to draw hash marks. If <code>null</code> no hash marks * will be drawn. */ private Color hashColor; /** Distance between left margin and where vertical dashes will be * drawn. */ protected int leftChildIndent; /** Distance to add to leftChildIndent to determine where cell * contents will be drawn. */ protected int rightChildIndent; /** Total distance that will be indented. The sum of leftChildIndent * and rightChildIndent. */ protected int totalChildIndent; /** Minimum preferred size. */ protected Dimension preferredMinSize; /** Index of the row that was last selected. */ protected int lastSelectedRow; /** Component that we're going to be drawing into. */ protected JTree tree; /** Renderer that is being used to do the actual cell drawing. */ transient protected TreeCellRenderer currentCellRenderer; /** Set to true if the renderer that is currently in the tree was * created by this instance. */ protected boolean createdRenderer; /** Editor for the tree. */ transient protected TreeCellEditor cellEditor; /** Set to true if editor that is currently in the tree was * created by this instance. */ protected boolean createdCellEditor; /** Set to false when editing and shouldSelectCell() returns true meaning * the node should be selected before editing, used in completeEditing. */ protected boolean stopEditingInCompleteEditing; /** Used to paint the TreeCellRenderer. */ protected CellRendererPane rendererPane; /** Size needed to completely display all the nodes. */ protected Dimension preferredSize; /** Is the preferredSize valid? */ protected boolean validCachedPreferredSize; /** Object responsible for handling sizing and expanded issues. */ protected AbstractLayoutCache treeState; /** Used for minimizing the drawing of vertical lines. */ protected Hashtable drawingCache; /** True if doing optimizations for a largeModel. Subclasses that * don't support this may wish to override createLayoutCache to not * return a FixedHeightLayoutCache instance. */ protected boolean largeModel; /** Reponsible for telling the TreeState the size needed for a node. */ protected AbstractLayoutCache.NodeDimensions nodeDimensions; /** Used to determine what to display. */ protected TreeModel treeModel; /** Model maintaing the selection. */ protected TreeSelectionModel treeSelectionModel; /** How much the depth should be offset to properly calculate * x locations. This is based on whether or not the root is visible, * and if the root handles are visible. */ protected int depthOffset; /** Last width the tree was at when painted. This is used when * !leftToRigth to notice the bounds have changed so that we can instruct * the TreeState to relayout. */ private int lastWidth; // Following 4 ivars are only valid when editing. /** When editing, this will be the Component that is doing the actual * editing. */ protected Component editingComponent; /** Path that is being edited. */ protected TreePath editingPath; /** Row that is being edited. Should only be referenced if * editingComponent is not null. */ protected int editingRow; /** Set to true if the editor has a different size than the renderer. */ protected boolean editorHasDifferentSize; /** Row correspondin to lead path. */ private int leadRow; /** If true, the property change event for LEAD_SELECTION_PATH_PROPERTY, * or ANCHOR_SELECTION_PATH_PROPERTY will not generate a repaint. */ private boolean ignoreLAChange; /** Indicates the orientation. */ private boolean leftToRight; // Cached listeners private PropertyChangeListener propertyChangeListener; private PropertyChangeListener selectionModelPropertyChangeListener; private MouseListener mouseListener; private FocusListener focusListener; private KeyListener keyListener; /** Used for large models, listens for moved/resized events and * updates the validCachedPreferredSize bit accordingly. */ private ComponentListener componentListener; /** Listens for CellEditor events. */ private CellEditorListener cellEditorListener; /** Updates the display when the selection changes. */ private TreeSelectionListener treeSelectionListener; /** Is responsible for updating the display based on model events. */ private TreeModelListener treeModelListener; /** Updates the treestate as the nodes expand. */ private TreeExpansionListener treeExpansionListener; public static ComponentUI createUI(JComponent x) { return new BasicTreeUI(); } public BasicTreeUI() { super(); } protected Color getHashColor() { return hashColor; } protected void setHashColor(Color color) { hashColor = color; } public void setLeftChildIndent(int newAmount) { leftChildIndent = newAmount; totalChildIndent = leftChildIndent + rightChildIndent; if(treeState != null) treeState.invalidateSizes(); updateSize(); } public int getLeftChildIndent() { return leftChildIndent; } public void setRightChildIndent(int newAmount) { rightChildIndent = newAmount; totalChildIndent = leftChildIndent + rightChildIndent; if(treeState != null) treeState.invalidateSizes(); updateSize(); } public int getRightChildIndent() { return rightChildIndent; } public void setExpandedIcon(Icon newG) { expandedIcon = newG; } public Icon getExpandedIcon() { return expandedIcon; } public void setCollapsedIcon(Icon newG) { collapsedIcon = newG; } public Icon getCollapsedIcon() { return collapsedIcon; } // // Methods for configuring the behavior of the tree. None of them // push the value to the JTree instance. You should really only // call these methods on the JTree. // /** * Updates the componentListener, if necessary. */ protected void setLargeModel(boolean largeModel) { if(getRowHeight() < 1) largeModel = false; if(this.largeModel != largeModel) { completeEditing(); this.largeModel = largeModel; treeState = createLayoutCache(); configureLayoutCache(); updateLayoutCacheExpandedNodes(); updateSize(); } } protected boolean isLargeModel() { return largeModel; } /** * Sets the row height, this is forwarded to the treeState. */ protected void setRowHeight(int rowHeight) { completeEditing(); if(treeState != null) { setLargeModel(tree.isLargeModel()); treeState.setRowHeight(rowHeight); updateSize(); } } protected int getRowHeight() { return (tree == null) ? -1 : tree.getRowHeight(); } /** * Sets the TreeCellRenderer to <code>tcr</code>. This invokes * <code>updateRenderer</code>. */ protected void setCellRenderer(TreeCellRenderer tcr) { completeEditing(); updateRenderer(); if(treeState != null) { treeState.invalidateSizes(); updateSize(); } } /** * Return currentCellRenderer, which will either be the trees * renderer, or defaultCellRenderer, which ever wasn't null. */ protected TreeCellRenderer getCellRenderer() { return currentCellRenderer; } /** * Sets the TreeModel. */ protected void setModel(TreeModel model) { completeEditing(); if(treeModel != null && treeModelListener != null) treeModel.removeTreeModelListener(treeModelListener); treeModel = model; if(treeModel != null) { if(treeModelListener != null) treeModel.addTreeModelListener(treeModelListener); } if(treeState != null) { treeState.setModel(model); updateLayoutCacheExpandedNodes(); updateSize(); } } protected TreeModel getModel() { return treeModel; } /** * Sets the root to being visible. */ protected void setRootVisible(boolean newValue) { completeEditing(); updateDepthOffset(); if(treeState != null) { treeState.setRootVisible(newValue); treeState.invalidateSizes(); updateSize(); } } protected boolean isRootVisible() { return (tree != null) ? tree.isRootVisible() : false; } /** * Determines whether the node handles are to be displayed. */ protected void setShowsRootHandles(boolean newValue) { completeEditing(); updateDepthOffset(); if(treeState != null) { treeState.invalidateSizes(); updateSize(); } } protected boolean getShowsRootHandles() { return (tree != null) ? tree.getShowsRootHandles() : false; } /** * Sets the cell editor. */ protected void setCellEditor(TreeCellEditor editor) { updateCellEditor(); } protected TreeCellEditor getCellEditor() { return (tree != null) ? tree.getCellEditor() : null; } /** * Configures the receiver to allow, or not allow, editing. */ protected void setEditable(boolean newValue) { updateCellEditor(); } protected boolean isEditable() { return (tree != null) ? tree.isEditable() : false; } /** * Resets the selection model. The appropriate listener are installed * on the model. */ protected void setSelectionModel(TreeSelectionModel newLSM) { completeEditing(); if(selectionModelPropertyChangeListener != null && treeSelectionModel != null) treeSelectionModel.removePropertyChangeListener (selectionModelPropertyChangeListener); if(treeSelectionListener != null && treeSelectionModel != null) treeSelectionModel.removeTreeSelectionListener (treeSelectionListener); treeSelectionModel = newLSM; if(treeSelectionModel != null) { if(selectionModelPropertyChangeListener != null) treeSelectionModel.addPropertyChangeListener (selectionModelPropertyChangeListener); if(treeSelectionListener != null) treeSelectionModel.addTreeSelectionListener (treeSelectionListener); if(treeState != null) treeState.setSelectionModel(treeSelectionModel); } else if(treeState != null) treeState.setSelectionModel(null); if(tree != null) tree.repaint(); } protected TreeSelectionModel getSelectionModel() { return treeSelectionModel; } // // TreeUI methods // /** * Returns the Rectangle enclosing the label portion that the * last item in path will be drawn into. Will return null if * any component in path is currently valid. */ public Rectangle getPathBounds(JTree tree, TreePath path) { if(tree != null && treeState != null) { Insets i = tree.getInsets(); Rectangle bounds = treeState.getBounds(path, null); if(bounds != null && i != null) { bounds.x += i.left; bounds.y += i.top; } return bounds; } return null; } /** * Returns the path for passed in row. If row is not visible * null is returned. */ public TreePath getPathForRow(JTree tree, int row) { return (treeState != null) ? treeState.getPathForRow(row) : null; } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -