4557 lines · 163.5 KB · Java
RawDownload
/* * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ 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.beans.*;import java.util.Enumeration;import java.util.Hashtable;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import javax.swing.plaf.ComponentUI;import javax.swing.plaf.UIResource;import javax.swing.plaf.TreeUI;import javax.swing.tree.*;import javax.swing.text.Position;import javax.swing.plaf.basic.DragRecognitionSupport.BeforeDrag;import sun.swing.SwingUtilities2; import sun.swing.DefaultLookup;import sun.swing.UIAction; /** * The basic L&F for a hierarchical data structure. * <p> * * @author Scott Violet * @author Shannon Hickey (drag and drop) */ public class BasicTreeUI extends TreeUI{    private static final StringBuilder BASELINE_COMPONENT_KEY =        new StringBuilder("Tree.baselineComponent");     // Old actions forward to an instance of this.    static private final Actions SHARED_ACTION = new Actions();     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. */    // WARNING: Be careful with the bounds held by treeState. They are    // always in terms of left-to-right. They get mapped to right-to-left    // by the various methods of this class.    protected AbstractLayoutCache  treeState;      /** Used for minimizing the drawing of vertical lines. */    protected Hashtable<TreePath,Boolean> 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;     // 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;     /** UI property indicating whether to paint lines */    private boolean paintLines = true;     /** UI property for painting dashed lines */    private boolean lineTypeDashed;     /**     * The time factor to treate the series of typed alphanumeric key     * as prefix for first letter navigation.     */    private long timeFactor = 1000L;     private Handler handler;     /**     * A temporary variable for communication between startEditingOnRelease     * and startEditing.     */    private MouseEvent releaseEvent;     public static ComponentUI createUI(JComponent x) {        return new BasicTreeUI();    }      static void loadActionMap(LazyActionMap map) {        map.put(new Actions(Actions.SELECT_PREVIOUS));        map.put(new Actions(Actions.SELECT_PREVIOUS_CHANGE_LEAD));        map.put(new Actions(Actions.SELECT_PREVIOUS_EXTEND_SELECTION));         map.put(new Actions(Actions.SELECT_NEXT));        map.put(new Actions(Actions.SELECT_NEXT_CHANGE_LEAD));        map.put(new Actions(Actions.SELECT_NEXT_EXTEND_SELECTION));         map.put(new Actions(Actions.SELECT_CHILD));        map.put(new Actions(Actions.SELECT_CHILD_CHANGE_LEAD));         map.put(new Actions(Actions.SELECT_PARENT));        map.put(new Actions(Actions.SELECT_PARENT_CHANGE_LEAD));         map.put(new Actions(Actions.SCROLL_UP_CHANGE_SELECTION));        map.put(new Actions(Actions.SCROLL_UP_CHANGE_LEAD));        map.put(new Actions(Actions.SCROLL_UP_EXTEND_SELECTION));         map.put(new Actions(Actions.SCROLL_DOWN_CHANGE_SELECTION));        map.put(new Actions(Actions.SCROLL_DOWN_EXTEND_SELECTION));        map.put(new Actions(Actions.SCROLL_DOWN_CHANGE_LEAD));         map.put(new Actions(Actions.SELECT_FIRST));        map.put(new Actions(Actions.SELECT_FIRST_CHANGE_LEAD));        map.put(new Actions(Actions.SELECT_FIRST_EXTEND_SELECTION));         map.put(new Actions(Actions.SELECT_LAST));        map.put(new Actions(Actions.SELECT_LAST_CHANGE_LEAD));        map.put(new Actions(Actions.SELECT_LAST_EXTEND_SELECTION));         map.put(new Actions(Actions.TOGGLE));         map.put(new Actions(Actions.CANCEL_EDITING));         map.put(new Actions(Actions.START_EDITING));         map.put(new Actions(Actions.SELECT_ALL));         map.put(new Actions(Actions.CLEAR_SELECTION));         map.put(new Actions(Actions.SCROLL_LEFT));        map.put(new Actions(Actions.SCROLL_RIGHT));         map.put(new Actions(Actions.SCROLL_LEFT_EXTEND_SELECTION));        map.put(new Actions(Actions.SCROLL_RIGHT_EXTEND_SELECTION));         map.put(new Actions(Actions.SCROLL_RIGHT_CHANGE_LEAD));        map.put(new Actions(Actions.SCROLL_LEFT_CHANGE_LEAD));         map.put(new Actions(Actions.EXPAND));        map.put(new Actions(Actions.COLLAPSE));        map.put(new Actions(Actions.MOVE_SELECTION_TO_PARENT));         map.put(new Actions(Actions.ADD_TO_SELECTION));        map.put(new Actions(Actions.TOGGLE_AND_ANCHOR));        map.put(new Actions(Actions.EXTEND_TO));        map.put(new Actions(Actions.MOVE_SELECTION_TO));         map.put(TransferHandler.getCutAction());        map.put(TransferHandler.getCopyAction());        map.put(TransferHandler.getPasteAction());    }      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();            updateLayoutCacheExpandedNodesIfNecessary();            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);            updateLayoutCacheExpandedNodesIfNecessary();            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)

Lines 1–500 of 4557.