FileDocCategorySizeDatePackage
SynthTreeUI.javaAPI DocJava SE 5 API22153Fri Aug 26 14:58:14 BST 2005javax.swing.plaf.synth

SynthTreeUI

public class SynthTreeUI extends BasicTreeUI implements SynthUI, PropertyChangeListener
Skinnable TreeUI.
version
1.23, 05/27/04
author
Scott Violet

Fields Summary
private SynthStyle
style
private SynthStyle
cellStyle
private SynthContext
paintContext
private boolean
drawHorizontalLines
private boolean
drawVerticalLines
private int
leadRow
private int
padding
private boolean
useTreeColors
private Icon
expandedIconWrapper
Constructors Summary
SynthTreeUI()

        expandedIconWrapper = new ExpandedIconWrapper();
    
Methods Summary
private voidadjustCellBounds(javax.swing.JTree tree, java.awt.Rectangle bounds, java.awt.Insets i)

        if (bounds != null) {
            if (i == null) {
                i = SynthLookAndFeel.EMPTY_UIRESOURCE_INSETS;
            }
            bounds.x += i.left;
            bounds.y += i.top;
        }
    
private voidconfigureRenderer(javax.swing.plaf.synth.SynthContext context)

        TreeCellRenderer renderer = tree.getCellRenderer();

        if (renderer instanceof DefaultTreeCellRenderer) {
            DefaultTreeCellRenderer r = (DefaultTreeCellRenderer)renderer;
            SynthStyle style = context.getStyle();

            context.setComponentState(ENABLED | SELECTED);
            Color color = r.getTextSelectionColor();
            if (color == null || (color instanceof UIResource)) {
                r.setTextSelectionColor(style.getColor(
                                     context, ColorType.TEXT_FOREGROUND));
            }
            color = r.getBackgroundSelectionColor();
            if (color == null || (color instanceof UIResource)) {
                r.setBackgroundSelectionColor(style.getColor(
                                        context, ColorType.TEXT_BACKGROUND));
            }

            context.setComponentState(ENABLED);
            color = r.getTextNonSelectionColor();
            if (color == null || color instanceof UIResource) {
                r.setTextNonSelectionColor(style.getColor(
                                        context, ColorType.TEXT_FOREGROUND));
            }
            color = r.getBackgroundNonSelectionColor();
            if (color instanceof UIResource) {
                r.setBackgroundNonSelectionColor(style.getColor(
                                  context, ColorType.TEXT_BACKGROUND));
            }
        }
    
protected javax.swing.tree.TreeCellEditorcreateDefaultCellEditor()

        TreeCellRenderer renderer = tree.getCellRenderer();
        DefaultTreeCellEditor editor;

	if(renderer != null && (renderer instanceof DefaultTreeCellRenderer)) {
	    editor = new SynthTreeCellEditor(tree, (DefaultTreeCellRenderer)
                                             renderer);
	}
        else {
            editor = new SynthTreeCellEditor(tree, null);
        }
        return editor;
    
protected javax.swing.tree.TreeCellRenderercreateDefaultCellRenderer()

        return new SynthTreeCellRenderer();
    
public static javax.swing.plaf.ComponentUIcreateUI(javax.swing.JComponent x)

	return new SynthTreeUI();
    
protected voiddrawCentered(java.awt.Component c, java.awt.Graphics graphics, javax.swing.Icon icon, int x, int y)

        int w = SynthIcon.getIconWidth(icon, paintContext);
        int h = SynthIcon.getIconHeight(icon, paintContext);

	SynthIcon.paintIcon(icon, paintContext, graphics, x - w/2, y - h/2, w,
                            h);
    
private intgetComponentState(javax.swing.JComponent c)

        return SynthLookAndFeel.getComponentState(c);
    
private intgetComponentState(javax.swing.JComponent c, javax.swing.plaf.synth.Region region)

        // Always treat the cell as selected, will be adjusted appropriately
        // when painted.
        return ENABLED | SELECTED;
    
private javax.swing.plaf.synth.SynthContextgetContext(javax.swing.JComponent c, javax.swing.plaf.synth.Region region)

        return getContext(c, region, getComponentState(c, region));
    
private javax.swing.plaf.synth.SynthContextgetContext(javax.swing.JComponent c, javax.swing.plaf.synth.Region region, int state)

        return SynthContext.getContext(SynthContext.class, c,
                                       region, cellStyle, state);
    
public javax.swing.plaf.synth.SynthContextgetContext(javax.swing.JComponent c)

        return getContext(c, getComponentState(c));
    
private javax.swing.plaf.synth.SynthContextgetContext(javax.swing.JComponent c, int state)

        return SynthContext.getContext(SynthContext.class, c,
                    SynthLookAndFeel.getRegion(c), style, state);
    
public javax.swing.IcongetExpandedIcon()

	return expandedIconWrapper;
    
private javax.swing.plaf.synth.RegiongetRegion(javax.swing.JTree c)

        return SynthLookAndFeel.getRegion(c);
    
protected intgetRowX(int row, int depth)

        return super.getRowX(row, depth) + padding;
    
protected voidinstallDefaults()

        updateStyle(tree);
    
protected voidinstallListeners()

        super.installListeners();
        tree.addPropertyChangeListener(this);
    
public voidpaint(java.awt.Graphics g, javax.swing.JComponent c)

        SynthContext context = getContext(c);

        paint(context, g);
        context.dispose();
    
protected voidpaint(javax.swing.plaf.synth.SynthContext context, java.awt.Graphics g)

        paintContext = context;

        updateLeadRow();

	Rectangle paintBounds = g.getClipBounds();
	Insets insets = tree.getInsets();
	TreePath initialPath = getClosestPathForLocation(tree, 0,
                                                         paintBounds.y);
	Enumeration paintingEnumerator = treeState.getVisiblePathsFrom
	                                      (initialPath);
	int row = treeState.getRowForPath(initialPath);
	int endY = paintBounds.y + paintBounds.height;
        TreeModel treeModel = tree.getModel();
        SynthContext cellContext = getContext(tree, Region.TREE_CELL);

	drawingCache.clear();

        setHashColor(context.getStyle().getColor(context,
                                                ColorType.FOREGROUND));

	if (paintingEnumerator != null) {
            // First pass, draw the rows

	    boolean done = false;
	    boolean isExpanded;
	    boolean hasBeenExpanded;
	    boolean isLeaf;
	    Rectangle boundsBuffer = new Rectangle();
            Rectangle rowBounds = new Rectangle(0, 0, tree.getWidth(),0);
	    Rectangle bounds;
	    TreePath path;
            TreeCellRenderer renderer = tree.getCellRenderer();
            DefaultTreeCellRenderer dtcr = (renderer instanceof
                       DefaultTreeCellRenderer) ? (DefaultTreeCellRenderer)
                       renderer : null;

            configureRenderer(cellContext);
	    while (!done && paintingEnumerator.hasMoreElements()) {
		path = (TreePath)paintingEnumerator.nextElement();
		if (path != null) {
		    isLeaf = treeModel.isLeaf(path.getLastPathComponent());
		    if (isLeaf) {
			isExpanded = hasBeenExpanded = false;
                    }
		    else {
			isExpanded = treeState.getExpandedState(path);
			hasBeenExpanded = tree.hasBeenExpanded(path);
		    }
		    bounds = treeState.getBounds(path, boundsBuffer);
                    adjustCellBounds(tree, bounds, insets);
                    rowBounds.y = bounds.y;
                    rowBounds.height = bounds.height;
		    paintRow(renderer, dtcr, context, cellContext, g,
                             paintBounds, insets, bounds, rowBounds, path,
                             row, isExpanded, hasBeenExpanded, isLeaf);
		    if ((bounds.y + bounds.height) >= endY) {
			done = true;
                    }
		}
		else {
		    done = true;
		}
		row++;
	    }

	    // Draw the connecting lines and controls.
	    // Find each parent and have them draw a line to their last child
            boolean rootVisible = tree.isRootVisible();
            TreePath parentPath = initialPath;
	    parentPath = parentPath.getParentPath();
	    while (parentPath != null) {
                paintVerticalPartOfLeg(g, paintBounds, insets, parentPath);
		drawingCache.put(parentPath, Boolean.TRUE);
		parentPath = parentPath.getParentPath();
	    }
	    done = false;
            paintingEnumerator = treeState.getVisiblePathsFrom(initialPath);
	    while (!done && paintingEnumerator.hasMoreElements()) {
		path = (TreePath)paintingEnumerator.nextElement();
		if (path != null) {
		    isLeaf = treeModel.isLeaf(path.getLastPathComponent());
		    if (isLeaf) {
			isExpanded = hasBeenExpanded = false;
                    }
		    else {
			isExpanded = treeState.getExpandedState(path);
			hasBeenExpanded = tree.hasBeenExpanded(path);
		    }
		    bounds = treeState.getBounds(path, boundsBuffer);
                    adjustCellBounds(tree, bounds, insets);
		    // See if the vertical line to the parent has been drawn.
		    parentPath = path.getParentPath();
		    if (parentPath != null) {
			if (drawingCache.get(parentPath) == null) {
                            paintVerticalPartOfLeg(g, paintBounds, insets,
                                                   parentPath);
			    drawingCache.put(parentPath, Boolean.TRUE);
			}
			paintHorizontalPartOfLeg(g,
                                                 paintBounds, insets, bounds,
                                                 path, row, isExpanded,
						 hasBeenExpanded, isLeaf);
		    }
		    else if (rootVisible && row == 0) {
			paintHorizontalPartOfLeg(g,
                                                 paintBounds, insets, bounds,
                                                 path, row, isExpanded,
						 hasBeenExpanded, isLeaf);
		    }
		    if (shouldPaintExpandControl(path, row, isExpanded,
                                                 hasBeenExpanded, isLeaf)) {
			paintExpandControl(g, paintBounds,
                                           insets, bounds, path, row,
                                           isExpanded, hasBeenExpanded,isLeaf);
		    }
		    if ((bounds.y + bounds.height) >= endY) {
			done = true;
                    }
		}
		else {
		    done = true;
		}
		row++;
	    }
	}
        cellContext.dispose();
	// Empty out the renderer pane, allowing renderers to be gc'ed.
	rendererPane.removeAll();
    
public voidpaintBorder(javax.swing.plaf.synth.SynthContext context, java.awt.Graphics g, int x, int y, int w, int h)

        context.getPainter().paintTreeBorder(context, g, x, y, w, h);
    
protected voidpaintHorizontalLine(java.awt.Graphics g, javax.swing.JComponent c, int y, int left, int right)

        paintContext.getStyle().getGraphicsUtils(paintContext).drawLine(
            paintContext, "Tree.horizontalLine", g, left, y, right, y);
    
protected voidpaintHorizontalPartOfLeg(java.awt.Graphics g, java.awt.Rectangle clipBounds, java.awt.Insets insets, java.awt.Rectangle bounds, javax.swing.tree.TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf)

        if (drawHorizontalLines) {
            super.paintHorizontalPartOfLeg(g, clipBounds, insets, bounds,
                                           path, row, isExpanded,
                                           hasBeenExpanded, isLeaf);
        }
    
protected voidpaintRow(javax.swing.tree.TreeCellRenderer renderer, javax.swing.tree.DefaultTreeCellRenderer dtcr, javax.swing.plaf.synth.SynthContext treeContext, javax.swing.plaf.synth.SynthContext cellContext, java.awt.Graphics g, java.awt.Rectangle clipBounds, java.awt.Insets insets, java.awt.Rectangle bounds, java.awt.Rectangle rowBounds, javax.swing.tree.TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf)

	// Don't paint the renderer if editing this row.
        boolean selected = tree.isRowSelected(row);

        if (selected) {
            cellContext.setComponentState(ENABLED | SELECTED);
        }
        else {
            cellContext.setComponentState(ENABLED);
        }
        if (dtcr != null && (dtcr.getBorderSelectionColor() instanceof
                             UIResource)) {
            dtcr.setBorderSelectionColor(style.getColor(
                                             cellContext, ColorType.FOCUS));
        }
        SynthLookAndFeel.updateSubregion(cellContext, g, rowBounds);
        cellContext.getPainter().paintTreeCellBackground(cellContext, g,
                    rowBounds.x, rowBounds.y, rowBounds.width,
                    rowBounds.height);
        cellContext.getPainter().paintTreeCellBorder(cellContext, g,
                    rowBounds.x, rowBounds.y, rowBounds.width,
                    rowBounds.height);
	if (editingComponent != null && editingRow == row) {
	    return;
        }

	int leadIndex;

	if (tree.hasFocus()) {
	    leadIndex = leadRow;
	}
	else {
	    leadIndex = -1;
        }

	Component component = renderer.getTreeCellRendererComponent(
                         tree, path.getLastPathComponent(),
                         selected, isExpanded, isLeaf, row,
                         (leadIndex == row));

	rendererPane.paintComponent(g, component, tree, bounds.x, bounds.y,
				    bounds.width, bounds.height, true);
    
protected voidpaintVerticalLine(java.awt.Graphics g, javax.swing.JComponent c, int x, int top, int bottom)

        paintContext.getStyle().getGraphicsUtils(paintContext).drawLine(
            paintContext, "Tree.verticalLine", g, x, top, x, bottom);
    
protected voidpaintVerticalPartOfLeg(java.awt.Graphics g, java.awt.Rectangle clipBounds, java.awt.Insets insets, javax.swing.tree.TreePath path)

        if (drawVerticalLines) {
            super.paintVerticalPartOfLeg(g, clipBounds, insets, path);
        }
    
public voidpropertyChange(java.beans.PropertyChangeEvent event)

        if (SynthLookAndFeel.shouldUpdateStyle(event)) {
            updateStyle((JTree)event.getSource());
        }
    
protected voiduninstallDefaults()

        SynthContext context = getContext(tree, ENABLED);

        style.uninstallDefaults(context);
        context.dispose();
        style = null;

        context = getContext(tree, Region.TREE_CELL, ENABLED);
        cellStyle.uninstallDefaults(context);
        context.dispose();
        cellStyle = null;


	if (tree.getTransferHandler() instanceof UIResource) {
	    tree.setTransferHandler(null);
	}
    
protected voiduninstallListeners()

        super.uninstallListeners();
        tree.removePropertyChangeListener(this);
    
public voidupdate(java.awt.Graphics g, javax.swing.JComponent c)

        SynthContext context = getContext(c);

        SynthLookAndFeel.update(context, g);
        context.getPainter().paintTreeBackground(context,
                          g, 0, 0, c.getWidth(), c.getHeight());
        paint(context, g);
        context.dispose();
    
private voidupdateLeadRow()

	leadRow = getRowForPath(tree, tree.getLeadSelectionPath());
    
private voidupdateStyle(javax.swing.JTree tree)

        SynthContext context = getContext(tree, ENABLED);
        SynthStyle oldStyle = style;

        style = SynthLookAndFeel.updateStyle(context, this);
        if (style != oldStyle) {
            Object value;

            setExpandedIcon(style.getIcon(context, "Tree.expandedIcon"));
            setCollapsedIcon(style.getIcon(context, "Tree.collapsedIcon"));

            setLeftChildIndent(style.getInt(context, "Tree.leftChildIndent",
                                            0));
            setRightChildIndent(style.getInt(context, "Tree.rightChildIndent",
                                             0));

            drawHorizontalLines = style.getBoolean(
                          context, "Tree.drawHorizontalLines",true);
            drawVerticalLines = style.getBoolean(
                        context, "Tree.drawVerticalLines", true);

	        value = style.get(context, "Tree.rowHeight");
	        if (value != null) {
	            LookAndFeel.installProperty(tree, "rowHeight", value);
	        }

	        value = style.get(context, "Tree.scrollsOnExpand");
	        LookAndFeel.installProperty(tree, "scrollsOnExpand",
			                            value != null? value : Boolean.TRUE);

            padding = style.getInt(context, "Tree.padding", 0);

            largeModel = (tree.isLargeModel() && tree.getRowHeight() > 0);

            useTreeColors = style.getBoolean(context,
                                  "Tree.rendererUseTreeColors", true);
            
            Boolean showsRootHandles = style.getBoolean(
                    context, "Tree.showsRootHandles", Boolean.TRUE);
            LookAndFeel.installProperty(
                    tree, JTree.SHOWS_ROOT_HANDLES_PROPERTY, showsRootHandles);

            if (oldStyle != null) {
                uninstallKeyboardActions();
                installKeyboardActions();
            }
        }
        context.dispose();

        context = getContext(tree, Region.TREE_CELL, ENABLED);
        cellStyle = SynthLookAndFeel.updateStyle(context, this);
        context.dispose();