- /*
- * @(#)SynthTreeUI.java 1.23 04/05/27
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
- package javax.swing.plaf.synth;
-
- 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.*;
- import javax.swing.plaf.basic.*;
- import javax.swing.tree.*;
- import javax.swing.text.Position;
- import sun.swing.plaf.synth.*;
-
- /**
- * Skinnable TreeUI.
- *
- * @version 1.23, 05/27/04
- * @author Scott Violet
- */
- class SynthTreeUI extends BasicTreeUI implements PropertyChangeListener,
- SynthUI {
- 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;
-
-
- public static ComponentUI createUI(JComponent x) {
- return new SynthTreeUI();
- }
-
- SynthTreeUI() {
- expandedIconWrapper = new ExpandedIconWrapper();
- }
-
- public Icon getExpandedIcon() {
- return expandedIconWrapper;
- }
-
- 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);
-
- 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();
- }
-
- protected void installListeners() {
- super.installListeners();
- tree.addPropertyChangeListener(this);
- }
-
- public SynthContext getContext(JComponent c) {
- return getContext(c, getComponentState(c));
- }
-
- private SynthContext getContext(JComponent c, int state) {
- return SynthContext.getContext(SynthContext.class, c,
- SynthLookAndFeel.getRegion(c), style, state);
- }
-
- private Region getRegion(JTree c) {
- return SynthLookAndFeel.getRegion(c);
- }
-
- private int getComponentState(JComponent c) {
- return SynthLookAndFeel.getComponentState(c);
- }
-
- 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(SynthContext.class, c,
- region, cellStyle, state);
- }
-
- private int getComponentState(JComponent c, Region region) {
- // Always treat the cell as selected, will be adjusted appropriately
- // when painted.
- return ENABLED | SELECTED;
- }
-
- 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;
- }
-
- protected TreeCellRenderer createDefaultCellRenderer() {
- return new SynthTreeCellRenderer();
- }
-
- 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);
- }
- }
-
- protected void uninstallListeners() {
- super.uninstallListeners();
- tree.removePropertyChangeListener(this);
- }
-
- 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();
- }
-
- public void paintBorder(SynthContext context, Graphics g, int x,
- int y, int w, int h) {
- context.getPainter().paintTreeBorder(context, g, x, y, w, h);
- }
-
- public void paint(Graphics g, JComponent c) {
- SynthContext context = getContext(c);
-
- paint(context, g);
- context.dispose();
- }
-
- private void adjustCellBounds(JTree tree, Rectangle bounds, Insets i){
- if (bounds != null) {
- if (i == null) {
- i = SynthLookAndFeel.EMPTY_UIRESOURCE_INSETS;
- }
- bounds.x += i.left;
- bounds.y += i.top;
- }
- }
-
- private void updateLeadRow() {
- leadRow = getRowForPath(tree, tree.getLeadSelectionPath());
- }
-
- protected void paint(SynthContext context, 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();
- }
-
- 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.getColor(
- context, ColorType.TEXT_FOREGROUND));
- }
- color = r.getBackgroundNonSelectionColor();
- if (color instanceof UIResource) {
- r.setBackgroundNonSelectionColor(style.getColor(
- context, ColorType.TEXT_BACKGROUND));
- }
- }
- }
-
- 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);
- }
- }
-
- 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);
- }
-
- protected void paintVerticalPartOfLeg(Graphics g,
- Rectangle clipBounds, Insets insets,
- TreePath path) {
- if (drawVerticalLines) {
- super.paintVerticalPartOfLeg(g, clipBounds, insets, path);
- }
- }
-
- 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);
- }
-
- protected 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) {
- // 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 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, x - w2, y - h2, w,
- h);
- }
-
- public void propertyChange(PropertyChangeEvent event) {
- if (SynthLookAndFeel.shouldUpdateStyle(event)) {
- updateStyle((JTree)event.getSource());
- }
- }
-
- protected int getRowX(int row, int depth) {
- return super.getRowX(row, depth) + padding;
- }
-
-
- private class SynthTreeCellRenderer extends DefaultTreeCellRenderer
- implements UIResource {
- SynthTreeCellRenderer() {
- }
- public String getName() {
- return "Tree.cellRenderer";
- }
- 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());
- }
- else {
- SynthLookAndFeel.resetSelectedUI();
- }
- return super.getTreeCellRendererComponent(tree, value, sel,
- expanded, leaf, row, hasFocus);
- }
- 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);
- }
-
- protected TreeCellEditor createTreeCellEditor() {
- JTextField tf = new JTextField() {
- public String getName() {
- return "Tree.cellEditor";
- }
- };
- DefaultCellEditor editor = new DefaultCellEditor(tf);
-
- // One click to edit.
- 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;
- }
- }
- }