| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
package javax.swing.plaf.synth;  | 
 | 
 | 
 | 
import java.awt.Color;  | 
 | 
import java.awt.Component;  | 
 | 
import java.awt.Graphics;  | 
 | 
import java.awt.Insets;  | 
 | 
import java.awt.Rectangle;  | 
 | 
import java.beans.PropertyChangeEvent;  | 
 | 
import java.beans.PropertyChangeListener;  | 
 | 
import java.util.Enumeration;  | 
 | 
import javax.swing.DefaultCellEditor;  | 
 | 
import javax.swing.Icon;  | 
 | 
import javax.swing.JComponent;  | 
 | 
import javax.swing.JTextField;  | 
 | 
import javax.swing.JTree;  | 
 | 
import javax.swing.LookAndFeel;  | 
 | 
import javax.swing.plaf.ComponentUI;  | 
 | 
import javax.swing.plaf.UIResource;  | 
 | 
import javax.swing.plaf.basic.BasicTreeUI;  | 
 | 
import javax.swing.tree.DefaultTreeCellEditor;  | 
 | 
import javax.swing.tree.DefaultTreeCellRenderer;  | 
 | 
import javax.swing.tree.TreeCellEditor;  | 
 | 
import javax.swing.tree.TreeCellRenderer;  | 
 | 
import javax.swing.tree.TreeModel;  | 
 | 
import javax.swing.tree.TreePath;  | 
 | 
import sun.swing.plaf.synth.SynthIcon;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
public class SynthTreeUI extends BasicTreeUI  | 
 | 
                         implements PropertyChangeListener, SynthUI { | 
 | 
    private SynthStyle style;  | 
 | 
    private SynthStyle cellStyle;  | 
 | 
 | 
 | 
    private SynthContext paintContext;  | 
 | 
 | 
 | 
    private boolean drawHorizontalLines;  | 
 | 
    private boolean drawVerticalLines;  | 
 | 
 | 
 | 
    private Object linesStyle;  | 
 | 
 | 
 | 
    private int padding;  | 
 | 
 | 
 | 
    private boolean useTreeColors;  | 
 | 
 | 
 | 
    private Icon expandedIconWrapper = new ExpandedIconWrapper();  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public static ComponentUI createUI(JComponent x) { | 
 | 
        return new SynthTreeUI();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public Icon getExpandedIcon() { | 
 | 
        return expandedIconWrapper;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void installDefaults() { | 
 | 
        updateStyle(tree);  | 
 | 
    }  | 
 | 
 | 
 | 
    private void updateStyle(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);  | 
 | 
            linesStyle = style.get(context, "Tree.linesStyle");  | 
 | 
 | 
 | 
                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();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void installListeners() { | 
 | 
        super.installListeners();  | 
 | 
        tree.addPropertyChangeListener(this);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public SynthContext getContext(JComponent c) { | 
 | 
        return getContext(c, SynthLookAndFeel.getComponentState(c));  | 
 | 
    }  | 
 | 
 | 
 | 
    private SynthContext getContext(JComponent c, int state) { | 
 | 
        return SynthContext.getContext(c, style, state);  | 
 | 
    }  | 
 | 
 | 
 | 
    private SynthContext getContext(JComponent c, Region region) { | 
 | 
        return getContext(c, region, getComponentState(c, region));  | 
 | 
    }  | 
 | 
 | 
 | 
    private SynthContext getContext(JComponent c, Region region, int state) { | 
 | 
        return SynthContext.getContext(c, region, cellStyle, state);  | 
 | 
    }  | 
 | 
 | 
 | 
    private int getComponentState(JComponent c, Region region) { | 
 | 
        // Always treat the cell as selected, will be adjusted appropriately  | 
 | 
          | 
 | 
        return ENABLED | SELECTED;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected TreeCellEditor createDefaultCellEditor() { | 
 | 
        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;  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected TreeCellRenderer createDefaultCellRenderer() { | 
 | 
        return new SynthTreeCellRenderer();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void uninstallDefaults() { | 
 | 
        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);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void uninstallListeners() { | 
 | 
        super.uninstallListeners();  | 
 | 
        tree.removePropertyChangeListener(this);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public void update(Graphics g, 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();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public void paintBorder(SynthContext context, Graphics g, int x,  | 
 | 
                            int y, int w, int h) { | 
 | 
        context.getPainter().paintTreeBorder(context, g, x, y, w, h);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public void paint(Graphics g, JComponent c) { | 
 | 
        SynthContext context = getContext(c);  | 
 | 
 | 
 | 
        paint(context, g);  | 
 | 
        context.dispose();  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    protected void paint(SynthContext context, Graphics g) { | 
 | 
        paintContext = context;  | 
 | 
 | 
 | 
        updateLeadSelectionRow();  | 
 | 
 | 
 | 
        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 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();  | 
 | 
                bounds = getPathBounds(tree, path);  | 
 | 
                if ((path != null) && (bounds != null)) { | 
 | 
                    isLeaf = treeModel.isLeaf(path.getLastPathComponent());  | 
 | 
                    if (isLeaf) { | 
 | 
                        isExpanded = hasBeenExpanded = false;  | 
 | 
                    }  | 
 | 
                    else { | 
 | 
                        isExpanded = treeState.getExpandedState(path);  | 
 | 
                        hasBeenExpanded = tree.hasBeenExpanded(path);  | 
 | 
                    }  | 
 | 
                    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.  | 
 | 
              | 
 | 
            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();  | 
 | 
                bounds = getPathBounds(tree, path);  | 
 | 
                if ((path != null) && (bounds != null)) { | 
 | 
                    isLeaf = treeModel.isLeaf(path.getLastPathComponent());  | 
 | 
                    if (isLeaf) { | 
 | 
                        isExpanded = hasBeenExpanded = false;  | 
 | 
                    }  | 
 | 
                    else { | 
 | 
                        isExpanded = treeState.getExpandedState(path);  | 
 | 
                        hasBeenExpanded = tree.hasBeenExpanded(path);  | 
 | 
                    }  | 
 | 
                      | 
 | 
                    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();  | 
 | 
 | 
 | 
        paintDropLine(g);  | 
 | 
 | 
 | 
          | 
 | 
        rendererPane.removeAll();  | 
 | 
 | 
 | 
        paintContext = null;  | 
 | 
    }  | 
 | 
 | 
 | 
    private void configureRenderer(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.getColorForState(  | 
 | 
                                        context, ColorType.TEXT_FOREGROUND));  | 
 | 
            }  | 
 | 
            color = r.getBackgroundNonSelectionColor();  | 
 | 
            if (color == null || color instanceof UIResource) { | 
 | 
                r.setBackgroundNonSelectionColor(style.getColorForState(  | 
 | 
                                  context, ColorType.TEXT_BACKGROUND));  | 
 | 
            }  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds,  | 
 | 
                                            Insets insets, Rectangle bounds,  | 
 | 
                                            TreePath path, int row,  | 
 | 
                                            boolean isExpanded,  | 
 | 
                                            boolean hasBeenExpanded, boolean  | 
 | 
                                            isLeaf) { | 
 | 
        if (drawHorizontalLines) { | 
 | 
            super.paintHorizontalPartOfLeg(g, clipBounds, insets, bounds,  | 
 | 
                                           path, row, isExpanded,  | 
 | 
                                           hasBeenExpanded, isLeaf);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void paintHorizontalLine(Graphics g, JComponent c, int y,  | 
 | 
                                      int left, int right) { | 
 | 
        paintContext.getStyle().getGraphicsUtils(paintContext).drawLine(  | 
 | 
            paintContext, "Tree.horizontalLine", g, left, y, right, y, linesStyle);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void paintVerticalPartOfLeg(Graphics g,  | 
 | 
                                          Rectangle clipBounds, Insets insets,  | 
 | 
                                          TreePath path) { | 
 | 
        if (drawVerticalLines) { | 
 | 
            super.paintVerticalPartOfLeg(g, clipBounds, insets, path);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void paintVerticalLine(Graphics g, JComponent c, int x, int top,  | 
 | 
                                    int bottom) { | 
 | 
        paintContext.getStyle().getGraphicsUtils(paintContext).drawLine(  | 
 | 
            paintContext, "Tree.verticalLine", g, x, top, x, bottom, linesStyle);  | 
 | 
    }  | 
 | 
 | 
 | 
    private void paintRow(TreeCellRenderer renderer,  | 
 | 
               DefaultTreeCellRenderer dtcr, SynthContext treeContext,  | 
 | 
               SynthContext cellContext, Graphics g, Rectangle clipBounds,  | 
 | 
               Insets insets, Rectangle bounds, Rectangle rowBounds,  | 
 | 
               TreePath path, int row, boolean isExpanded,  | 
 | 
               boolean hasBeenExpanded, boolean isLeaf) { | 
 | 
          | 
 | 
        boolean selected = tree.isRowSelected(row);  | 
 | 
 | 
 | 
        JTree.DropLocation dropLocation = tree.getDropLocation();  | 
 | 
        boolean isDrop = dropLocation != null  | 
 | 
                         && dropLocation.getChildIndex() == -1  | 
 | 
                         && path == dropLocation.getPath();  | 
 | 
 | 
 | 
        int state = ENABLED;  | 
 | 
        if (selected || isDrop) { | 
 | 
            state |= SELECTED;  | 
 | 
        }  | 
 | 
 | 
 | 
        if (tree.isFocusOwner() && row == getLeadSelectionRow()) { | 
 | 
            state |= FOCUSED;  | 
 | 
        }  | 
 | 
 | 
 | 
        cellContext.setComponentState(state);  | 
 | 
 | 
 | 
        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 = getLeadSelectionRow();  | 
 | 
        }  | 
 | 
        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);  | 
 | 
    }  | 
 | 
 | 
 | 
    private int findCenteredX(int x, int iconWidth) { | 
 | 
        return tree.getComponentOrientation().isLeftToRight()  | 
 | 
               ? x - (int)Math.ceil(iconWidth / 2.0)  | 
 | 
               : x - (int)Math.floor(iconWidth / 2.0);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void paintExpandControl(Graphics g, Rectangle clipBounds,  | 
 | 
            Insets insets, Rectangle bounds, TreePath path, int row,  | 
 | 
            boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf) { | 
 | 
        //modify the paintContext's state to match the state for the row  | 
 | 
        //this is a hack in that it requires knowledge of the subsequent  | 
 | 
        //method calls. The point is, the context used in drawCentered  | 
 | 
          | 
 | 
        boolean isSelected = tree.getSelectionModel().isPathSelected(path);  | 
 | 
        int state = paintContext.getComponentState();  | 
 | 
        if (isSelected) { | 
 | 
            paintContext.setComponentState(state | SynthConstants.SELECTED);  | 
 | 
        }  | 
 | 
        super.paintExpandControl(g, clipBounds, insets, bounds, path, row,  | 
 | 
                isExpanded, hasBeenExpanded, isLeaf);  | 
 | 
        paintContext.setComponentState(state);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void drawCentered(Component c, Graphics graphics, Icon icon,  | 
 | 
                                int x, int y) { | 
 | 
        int w = SynthIcon.getIconWidth(icon, paintContext);  | 
 | 
        int h = SynthIcon.getIconHeight(icon, paintContext);  | 
 | 
 | 
 | 
        SynthIcon.paintIcon(icon, paintContext, graphics,  | 
 | 
                            findCenteredX(x, w),  | 
 | 
                            y - h/2, w, h);  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    public void propertyChange(PropertyChangeEvent event) { | 
 | 
        if (SynthLookAndFeel.shouldUpdateStyle(event)) { | 
 | 
            updateStyle((JTree)event.getSource());  | 
 | 
        }  | 
 | 
 | 
 | 
        if ("dropLocation" == event.getPropertyName()) { | 
 | 
            JTree.DropLocation oldValue = (JTree.DropLocation)event.getOldValue();  | 
 | 
            repaintDropLocation(oldValue);  | 
 | 
            repaintDropLocation(tree.getDropLocation());  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected void paintDropLine(Graphics g) { | 
 | 
        JTree.DropLocation loc = tree.getDropLocation();  | 
 | 
        if (!isDropLine(loc)) { | 
 | 
            return;  | 
 | 
        }  | 
 | 
 | 
 | 
        Color c = (Color)style.get(paintContext, "Tree.dropLineColor");  | 
 | 
        if (c != null) { | 
 | 
            g.setColor(c);  | 
 | 
            Rectangle rect = getDropLineRect(loc);  | 
 | 
            g.fillRect(rect.x, rect.y, rect.width, rect.height);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    private void repaintDropLocation(JTree.DropLocation loc) { | 
 | 
        if (loc == null) { | 
 | 
            return;  | 
 | 
        }  | 
 | 
 | 
 | 
        Rectangle r;  | 
 | 
 | 
 | 
        if (isDropLine(loc)) { | 
 | 
            r = getDropLineRect(loc);  | 
 | 
        } else { | 
 | 
            r = tree.getPathBounds(loc.getPath());  | 
 | 
            if (r != null) { | 
 | 
                r.x = 0;  | 
 | 
                r.width = tree.getWidth();  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        if (r != null) { | 
 | 
            tree.repaint(r);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
     */  | 
 | 
    @Override  | 
 | 
    protected int getRowX(int row, int depth) { | 
 | 
        return super.getRowX(row, depth) + padding;  | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
    private class SynthTreeCellRenderer extends DefaultTreeCellRenderer  | 
 | 
                               implements UIResource { | 
 | 
        SynthTreeCellRenderer() { | 
 | 
        }  | 
 | 
 | 
 | 
        @Override  | 
 | 
        public String getName() { | 
 | 
            return "Tree.cellRenderer";  | 
 | 
        }  | 
 | 
 | 
 | 
        @Override  | 
 | 
        public Component getTreeCellRendererComponent(JTree tree, Object value,  | 
 | 
                                                      boolean sel,  | 
 | 
                                                      boolean expanded,  | 
 | 
                                                      boolean leaf, int row,  | 
 | 
                                                      boolean hasFocus) { | 
 | 
            if (!useTreeColors && (sel || hasFocus)) { | 
 | 
                SynthLookAndFeel.setSelectedUI((SynthLabelUI)SynthLookAndFeel.  | 
 | 
                             getUIOfType(getUI(), SynthLabelUI.class),  | 
 | 
                                   sel, hasFocus, tree.isEnabled(), false);  | 
 | 
            }  | 
 | 
            else { | 
 | 
                SynthLookAndFeel.resetSelectedUI();  | 
 | 
            }  | 
 | 
            return super.getTreeCellRendererComponent(tree, value, sel,  | 
 | 
                                                      expanded, leaf, row, hasFocus);  | 
 | 
        }  | 
 | 
 | 
 | 
        @Override  | 
 | 
        public void paint(Graphics g) { | 
 | 
            paintComponent(g);  | 
 | 
            if (hasFocus) { | 
 | 
                SynthContext context = getContext(tree, Region.TREE_CELL);  | 
 | 
 | 
 | 
                if (context.getStyle() == null) { | 
 | 
                    assert false: "SynthTreeCellRenderer is being used " +  | 
 | 
                        "outside of UI that created it";  | 
 | 
                    return;  | 
 | 
                }  | 
 | 
                int imageOffset = 0;  | 
 | 
                Icon currentI = getIcon();  | 
 | 
 | 
 | 
                if(currentI != null && getText() != null) { | 
 | 
                    imageOffset = currentI.getIconWidth() +  | 
 | 
                                          Math.max(0, getIconTextGap() - 1);  | 
 | 
                }  | 
 | 
                if (selected) { | 
 | 
                    context.setComponentState(ENABLED | SELECTED);  | 
 | 
                }  | 
 | 
                else { | 
 | 
                    context.setComponentState(ENABLED);  | 
 | 
                }  | 
 | 
                if(getComponentOrientation().isLeftToRight()) { | 
 | 
                    context.getPainter().paintTreeCellFocus(context, g,  | 
 | 
                            imageOffset, 0, getWidth() - imageOffset,  | 
 | 
                            getHeight());  | 
 | 
                }  | 
 | 
                else { | 
 | 
                    context.getPainter().paintTreeCellFocus(context, g,  | 
 | 
                            0, 0, getWidth() - imageOffset, getHeight());  | 
 | 
                }  | 
 | 
                context.dispose();  | 
 | 
            }  | 
 | 
            SynthLookAndFeel.resetSelectedUI();  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
 | 
 | 
    private static class SynthTreeCellEditor extends DefaultTreeCellEditor { | 
 | 
        public SynthTreeCellEditor(JTree tree,  | 
 | 
                                   DefaultTreeCellRenderer renderer) { | 
 | 
            super(tree, renderer);  | 
 | 
            setBorderSelectionColor(null);  | 
 | 
        }  | 
 | 
 | 
 | 
        @Override  | 
 | 
        protected TreeCellEditor createTreeCellEditor() { | 
 | 
            JTextField tf = new JTextField() { | 
 | 
                @Override  | 
 | 
                public String getName() { | 
 | 
                    return "Tree.cellEditor";  | 
 | 
                }  | 
 | 
            };  | 
 | 
            DefaultCellEditor editor = new DefaultCellEditor(tf);  | 
 | 
 | 
 | 
              | 
 | 
            editor.setClickCountToStart(1);  | 
 | 
            return editor;  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
    //  | 
 | 
    // BasicTreeUI directly uses expandIcon outside of the Synth methods.  | 
 | 
    // To get the correct context we return an instance of this that fetches  | 
 | 
    // the SynthContext as needed.  | 
 | 
      | 
 | 
    private class ExpandedIconWrapper extends SynthIcon { | 
 | 
        public void paintIcon(SynthContext context, Graphics g, int x,  | 
 | 
                              int y, int w, int h) { | 
 | 
            if (context == null) { | 
 | 
                context = getContext(tree);  | 
 | 
                SynthIcon.paintIcon(expandedIcon, context, g, x, y, w, h);  | 
 | 
                context.dispose();  | 
 | 
            }  | 
 | 
            else { | 
 | 
                SynthIcon.paintIcon(expandedIcon, context, g, x, y, w, h);  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        public int getIconWidth(SynthContext context) { | 
 | 
            int width;  | 
 | 
            if (context == null) { | 
 | 
                context = getContext(tree);  | 
 | 
                width = SynthIcon.getIconWidth(expandedIcon, context);  | 
 | 
                context.dispose();  | 
 | 
            }  | 
 | 
            else { | 
 | 
                width = SynthIcon.getIconWidth(expandedIcon, context);  | 
 | 
            }  | 
 | 
            return width;  | 
 | 
        }  | 
 | 
 | 
 | 
        public int getIconHeight(SynthContext context) { | 
 | 
            int height;  | 
 | 
            if (context == null) { | 
 | 
                context = getContext(tree);  | 
 | 
                height = SynthIcon.getIconHeight(expandedIcon, context);  | 
 | 
                context.dispose();  | 
 | 
            }  | 
 | 
            else { | 
 | 
                height = SynthIcon.getIconHeight(expandedIcon, context);  | 
 | 
            }  | 
 | 
            return height;  | 
 | 
        }  | 
 | 
    }  | 
 | 
}  |