synthtreeui.java

来自「java jdk 1.4的源码」· Java 代码 · 共 1,971 行 · 第 1/5 页

JAVA
1,971
字号
/* * @(#)SynthTreeUI.java	1.18 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.java.swing.plaf.gtk;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.*;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;/** * SynthTreeUI provides space for a control icon and the renderer * portion of a node. The leading edge of the renderer is calculated * by <code>Tree.indent</code> * depth - 1 + <code>Tree.controlSize</code>. * The icon is centered at leading renderer edge - * <code>Tree.trailingControlOffset</code>. The horizontal separators, * if drawn, are drawn from the leading edge of the renderer - * <code>Tree.trailingControlOffset</code> to the leading edge of * renderer - <code>Tree.trailingLegBufferOffset</code>. * <p> * * @version 1.18, 01/23/03 (based on BasicTreeUI v 1.155) * @author Scott Violet */class SynthTreeUI extends TreeUI implements PropertyChangeListener, SynthUI,           LazyActionMap.Loader {    private static final TreeDragGestureRecognizer defaultDragRecognizer        = new TreeDragGestureRecognizer();    private static DropTargetListener defaultDropTargetListener = null;        private static final TransferHandler defaultTransferHandler        = new TreeTransferHandler();    /**     * Icon to use for nodes that are collapsed.     */    private Icon collapsedIcon;    /**     * Icon to use when a node is expanded.     */    private Icon expandedIcon;    /**     * The Tree!     */    private JTree tree;    /**     * Used during drawing to track which nodes have had their separators     * drawn.     */    private Map drawingCache;    /**     * Offset, from trailing margin, to center of control icon.     */    private int trailingControlOffset;    /**     * Total size to allow to expand/collapse icon. This includes the     * leading padding.     */    private int controlSize;     /**     * Pixels to indent children, this is not necessarily controlSize.     */    private int indent;   /**     * Amount of space to leave between node and horizontal separators as     * measured from trailing margin.     */    private int trailingLegBufferOffset;    /**     * Indicates if the horizontal legs should be drawn.     */    private boolean drawHorizontalLegs;    /**     * Indicates if the vertical legs should be drawn.     */    private boolean drawVerticalLegs;    /**     * Whether or not the focus border should be drawn around the renderer.     */    private boolean drawsFocusBorder;    /**     * The offset the root should be rendered at. This isn't a pixel     * value, rather an integer that will be offset by the getIndent.     * The value depends upon if the root is visible, and if the root handles     * are visible.     */    private int rootOffset;    /**     * If true, when TreeSelectionListener.valueChanged is invoked it will     * NOT invoke stopCellEditing. This is used when the selection is changed     * as a result of editing so that the editing session isn't canceled     * immediately.     */    private boolean stopEditingWhenSelectionChanges;    /**     * Used to paint the TreeCellRenderer.     */    private CellRendererPane  rendererPane;    /**     * Preferred size, calculated from the AbstractLayoutCache.     */    private Dimension preferredSize;    /**     * Is the preferredSize valid?     */    protected boolean validCachedPreferredSize;    /**     * Object responsible for handling sizing and expanded issues.     */    private AbstractLayoutCache  treeState;    /**     * True if doing optimizations for a largeModel. This is used     * to determine the type of AbstractLayoutCache to create.     */    private boolean largeModel;    /**     * Reponsible for telling the TreeState the size needed for a node.     */    private AbstractLayoutCache.NodeDimensions     nodeDimensions;    /**     * Used during editing to hold editing related state.     */    private EditingState editingState;    /**     * Indicates the orientation. This is cached as used quite extensively     * while painting.     */    private boolean leftToRight;    /**     * Row corresponding to the lead path.     */    private int leadRow;    // Cached listeners    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;    private CellEditorListener cellEditorListener;    private TreeSelectionListener treeSelectionListener;    private TreeModelListener treeModelListener;    private TreeExpansionListener treeExpansionListener;    private SynthStyle style;    private SynthStyle cellStyle;    public static ComponentUI createUI(JComponent x) {	return new SynthTreeUI();    }    /**     * Ensures that the rows identified by beginRow through endRow are     * visible.     */    private static void ensureRowsAreVisible(JTree tree, int beginRow,                                             int endRow) {	if (beginRow >= 0 && endRow < tree.getRowCount()) {            // PENDING: needs to be updated.            SynthTreeUI ui = (SynthTreeUI)tree.getUI();            SynthContext context = ui.getContext(tree);            boolean scrollVert = context.getStyle().getBoolean(context,                              "Tree.scrollsHorizontallyAndVertically", false);            context.dispose();	    if (beginRow == endRow) {		Rectangle scrollBounds = tree.getPathBounds(                                tree.getPathForRow(beginRow));		if (scrollBounds != null) {                    if (!scrollVert) {                        scrollBounds.x = tree.getVisibleRect().x;                        scrollBounds.width = 1;                    }		    tree.scrollRectToVisible(scrollBounds);		}	    }	    else {		Rectangle beginRect = tree.getPathBounds(tree.getPathForRow                                                           (beginRow));		Rectangle visRect = tree.getVisibleRect();		Rectangle testRect = beginRect;		int beginY = beginRect.y;		int maxY = beginY + visRect.height;		for (int counter = beginRow + 1; counter <= endRow; counter++){		    testRect = tree.getPathBounds(tree.getPathForRow(counter));		    if ((testRect.y + testRect.height) > maxY) {			counter = endRow;                    }		}		tree.scrollRectToVisible(new Rectangle(visRect.x, beginY, 1,						  testRect.y + testRect.height-						  beginY));	    }	}    }    //    // ComponentUI methods    //    /**     * Returns the preferred size needed to properly renderer the tree.     */    public Dimension getPreferredSize(JComponent c) {	if (!validCachedPreferredSize) {	    updateCachedPreferredSize();        }        return new Dimension(preferredSize);    }    /**      * Returns the minimum size for this component.  Which will be      * the min preferred size or 0, 0.      */    public Dimension getMinimumSize(JComponent c) {	return new Dimension(0, 0);    }    /**      * Returns the maximum size for this component, which will be the      * preferred size if the instance is currently in a JTree, or 0, 0.      */    public Dimension getMaximumSize(JComponent c) {        return getPreferredSize(tree);    }    //    // 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) {	    Rectangle        bounds = treeState.getBounds(path, null);            adjustCellBounds(tree, bounds, null);	    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;    }    /**      * Returns the row that the last item identified in path is visible      * at.  Will return -1 if any of the elements in path are not      * currently visible.      */    public int getRowForPath(JTree tree, TreePath path) {	return (treeState != null) ? treeState.getRowForPath(path) : -1;    }    /**      * Returns the number of rows that are being displayed.      */    public int getRowCount(JTree tree) {	return (treeState != null) ? treeState.getRowCount() : 0;    }    /**      * Returns the path to the node that is closest to x,y.  If      * there is nothing currently visible this will return null, otherwise      * it'll always return a valid path.  If you need to test if the      * returned object is exactly at x, y you should get the bounds for      * the returned path and test x, y against that.      */    public TreePath getClosestPathForLocation(JTree tree, int x, int y) {	if (tree != null && treeState != null) {	    Insets          i = tree.getInsets();            if (leftToRight) {                x -= i.left;            }            else {                x = tree.getWidth() - x - i.right;            }	    return treeState.getPathClosestTo(x, y - i.top);	}	return null;    }    /**      * Returns true if the tree is being edited.  The item that is being      * edited can be returned by getEditingPath().      */    public boolean isEditing(JTree tree) {	return (editingState != null);    }    /**      * Stops the current editing session.  This has no effect if the      * tree isn't being edited.  Returns true if the editor allows the      * editing session to stop.      */    public boolean stopEditing(JTree tree) {	if (editingState != null && tree.getCellEditor().stopCellEditing()) {	    completeEditing(false, false, true);	    return true;	}	return false;    }    /**      * Cancels the current editing session.      */    public void cancelEditing(JTree tree) {	if (editingState != null) {	    completeEditing(false, true, false);	}    }    /**      * Selects the last item in path and tries to edit it.  Editing will      * fail if the CellEditor won't allow it for the selected item.      */    public void startEditingAtPath(JTree tree, TreePath path) {	tree.scrollPathToVisible(path);	if (path != null && tree.isVisible(path)) {	    startEditing(path, null);        }    }    /**     * Returns the path to the element that is being edited.     */    public TreePath getEditingPath(JTree tree) {	return (editingState != null) ? editingState.path : null;    }    //    // Install methods    //    public SynthTreeUI() {        preferredSize = new Dimension();    }    public void installUI(JComponent c) {        if (c == null) {	    throw new NullPointerException(                          "null component passed to SynthTreeUI.installUI()");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?