0N/A/*
3261N/A * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/Apackage javax.swing.plaf.synth;
0N/A
1173N/Aimport java.awt.Color;
1173N/Aimport java.awt.Component;
1173N/Aimport java.awt.Graphics;
1173N/Aimport java.awt.Insets;
1173N/Aimport java.awt.Rectangle;
1173N/Aimport java.beans.PropertyChangeEvent;
1173N/Aimport java.beans.PropertyChangeListener;
1173N/Aimport java.util.Enumeration;
1173N/Aimport javax.swing.DefaultCellEditor;
1173N/Aimport javax.swing.Icon;
1173N/Aimport javax.swing.JComponent;
1173N/Aimport javax.swing.JTextField;
1173N/Aimport javax.swing.JTree;
1173N/Aimport javax.swing.LookAndFeel;
1173N/Aimport javax.swing.plaf.ComponentUI;
1173N/Aimport javax.swing.plaf.UIResource;
1173N/Aimport javax.swing.plaf.basic.BasicTreeUI;
1173N/Aimport javax.swing.tree.DefaultTreeCellEditor;
1173N/Aimport javax.swing.tree.DefaultTreeCellRenderer;
1173N/Aimport javax.swing.tree.TreeCellEditor;
1173N/Aimport javax.swing.tree.TreeCellRenderer;
1173N/Aimport javax.swing.tree.TreeModel;
1173N/Aimport javax.swing.tree.TreePath;
1173N/Aimport sun.swing.plaf.synth.SynthIcon;
0N/A
0N/A/**
1999N/A * Provides the Synth L&F UI delegate for
1999N/A * {@link javax.swing.JTree}.
0N/A *
0N/A * @author Scott Violet
1999N/A * @since 1.7
0N/A */
1999N/Apublic class SynthTreeUI extends BasicTreeUI
1999N/A implements PropertyChangeListener, SynthUI {
0N/A private SynthStyle style;
0N/A private SynthStyle cellStyle;
0N/A
0N/A private SynthContext paintContext;
0N/A
0N/A private boolean drawHorizontalLines;
0N/A private boolean drawVerticalLines;
0N/A
0N/A private Object linesStyle;
0N/A
0N/A private int padding;
0N/A
0N/A private boolean useTreeColors;
0N/A
1999N/A private Icon expandedIconWrapper = new ExpandedIconWrapper();
0N/A
1999N/A /**
1999N/A * Creates a new UI object for the given component.
1999N/A *
1999N/A * @param x component to create UI object for
1999N/A * @return the UI object
1999N/A */
0N/A public static ComponentUI createUI(JComponent x) {
0N/A return new SynthTreeUI();
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A public Icon getExpandedIcon() {
0N/A return expandedIconWrapper;
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A protected void installDefaults() {
0N/A updateStyle(tree);
0N/A }
0N/A
0N/A private void updateStyle(JTree tree) {
0N/A SynthContext context = getContext(tree, ENABLED);
0N/A SynthStyle oldStyle = style;
0N/A
0N/A style = SynthLookAndFeel.updateStyle(context, this);
0N/A if (style != oldStyle) {
0N/A Object value;
0N/A
0N/A setExpandedIcon(style.getIcon(context, "Tree.expandedIcon"));
0N/A setCollapsedIcon(style.getIcon(context, "Tree.collapsedIcon"));
0N/A
0N/A setLeftChildIndent(style.getInt(context, "Tree.leftChildIndent",
0N/A 0));
0N/A setRightChildIndent(style.getInt(context, "Tree.rightChildIndent",
0N/A 0));
0N/A
0N/A drawHorizontalLines = style.getBoolean(
0N/A context, "Tree.drawHorizontalLines",true);
0N/A drawVerticalLines = style.getBoolean(
0N/A context, "Tree.drawVerticalLines", true);
0N/A linesStyle = style.get(context, "Tree.linesStyle");
0N/A
0N/A value = style.get(context, "Tree.rowHeight");
0N/A if (value != null) {
0N/A LookAndFeel.installProperty(tree, "rowHeight", value);
0N/A }
0N/A
0N/A value = style.get(context, "Tree.scrollsOnExpand");
0N/A LookAndFeel.installProperty(tree, "scrollsOnExpand",
0N/A value != null? value : Boolean.TRUE);
0N/A
0N/A padding = style.getInt(context, "Tree.padding", 0);
0N/A
0N/A largeModel = (tree.isLargeModel() && tree.getRowHeight() > 0);
0N/A
0N/A useTreeColors = style.getBoolean(context,
0N/A "Tree.rendererUseTreeColors", true);
0N/A
0N/A Boolean showsRootHandles = style.getBoolean(
0N/A context, "Tree.showsRootHandles", Boolean.TRUE);
0N/A LookAndFeel.installProperty(
0N/A tree, JTree.SHOWS_ROOT_HANDLES_PROPERTY, showsRootHandles);
0N/A
0N/A if (oldStyle != null) {
0N/A uninstallKeyboardActions();
0N/A installKeyboardActions();
0N/A }
0N/A }
0N/A context.dispose();
0N/A
0N/A context = getContext(tree, Region.TREE_CELL, ENABLED);
0N/A cellStyle = SynthLookAndFeel.updateStyle(context, this);
0N/A context.dispose();
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A protected void installListeners() {
0N/A super.installListeners();
0N/A tree.addPropertyChangeListener(this);
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A public SynthContext getContext(JComponent c) {
1999N/A return getContext(c, SynthLookAndFeel.getComponentState(c));
0N/A }
0N/A
0N/A private SynthContext getContext(JComponent c, int state) {
0N/A return SynthContext.getContext(SynthContext.class, c,
0N/A SynthLookAndFeel.getRegion(c), style, state);
0N/A }
0N/A
0N/A private SynthContext getContext(JComponent c, Region region) {
0N/A return getContext(c, region, getComponentState(c, region));
0N/A }
0N/A
0N/A private SynthContext getContext(JComponent c, Region region, int state) {
0N/A return SynthContext.getContext(SynthContext.class, c,
0N/A region, cellStyle, state);
0N/A }
0N/A
0N/A private int getComponentState(JComponent c, Region region) {
0N/A // Always treat the cell as selected, will be adjusted appropriately
0N/A // when painted.
0N/A return ENABLED | SELECTED;
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A protected TreeCellEditor createDefaultCellEditor() {
0N/A TreeCellRenderer renderer = tree.getCellRenderer();
0N/A DefaultTreeCellEditor editor;
0N/A
0N/A if(renderer != null && (renderer instanceof DefaultTreeCellRenderer)) {
0N/A editor = new SynthTreeCellEditor(tree, (DefaultTreeCellRenderer)
0N/A renderer);
0N/A }
0N/A else {
0N/A editor = new SynthTreeCellEditor(tree, null);
0N/A }
0N/A return editor;
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A protected TreeCellRenderer createDefaultCellRenderer() {
0N/A return new SynthTreeCellRenderer();
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A protected void uninstallDefaults() {
0N/A SynthContext context = getContext(tree, ENABLED);
0N/A
0N/A style.uninstallDefaults(context);
0N/A context.dispose();
0N/A style = null;
0N/A
0N/A context = getContext(tree, Region.TREE_CELL, ENABLED);
0N/A cellStyle.uninstallDefaults(context);
0N/A context.dispose();
0N/A cellStyle = null;
0N/A
0N/A
0N/A if (tree.getTransferHandler() instanceof UIResource) {
0N/A tree.setTransferHandler(null);
0N/A }
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A protected void uninstallListeners() {
0N/A super.uninstallListeners();
0N/A tree.removePropertyChangeListener(this);
0N/A }
0N/A
1999N/A /**
2146N/A * Notifies this UI delegate to repaint the specified component.
2146N/A * This method paints the component background, then calls
2146N/A * the {@link #paint(SynthContext,Graphics)} method.
2146N/A *
2146N/A * <p>In general, this method does not need to be overridden by subclasses.
2146N/A * All Look and Feel rendering code should reside in the {@code paint} method.
2146N/A *
2146N/A * @param g the {@code Graphics} object used for painting
2146N/A * @param c the component being painted
2146N/A * @see #paint(SynthContext,Graphics)
1999N/A */
1173N/A @Override
0N/A public void update(Graphics g, JComponent c) {
0N/A SynthContext context = getContext(c);
0N/A
0N/A SynthLookAndFeel.update(context, g);
0N/A context.getPainter().paintTreeBackground(context,
0N/A g, 0, 0, c.getWidth(), c.getHeight());
0N/A paint(context, g);
0N/A context.dispose();
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1999N/A @Override
0N/A public void paintBorder(SynthContext context, Graphics g, int x,
0N/A int y, int w, int h) {
0N/A context.getPainter().paintTreeBorder(context, g, x, y, w, h);
0N/A }
0N/A
1999N/A /**
2146N/A * Paints the specified component according to the Look and Feel.
2146N/A * <p>This method is not used by Synth Look and Feel.
2146N/A * Painting is handled by the {@link #paint(SynthContext,Graphics)} method.
2146N/A *
2146N/A * @param g the {@code Graphics} object used for painting
2146N/A * @param c the component being painted
2146N/A * @see #paint(SynthContext,Graphics)
1999N/A */
1173N/A @Override
0N/A public void paint(Graphics g, JComponent c) {
0N/A SynthContext context = getContext(c);
0N/A
0N/A paint(context, g);
0N/A context.dispose();
0N/A }
0N/A
1999N/A /**
1999N/A * Paints the specified component.
1999N/A *
1999N/A * @param context context for the component being painted
2146N/A * @param g the {@code Graphics} object used for painting
2146N/A * @see #update(Graphics,JComponent)
1999N/A */
0N/A protected void paint(SynthContext context, Graphics g) {
0N/A paintContext = context;
0N/A
1999N/A updateLeadSelectionRow();
0N/A
0N/A Rectangle paintBounds = g.getClipBounds();
0N/A Insets insets = tree.getInsets();
0N/A TreePath initialPath = getClosestPathForLocation(tree, 0,
0N/A paintBounds.y);
0N/A Enumeration paintingEnumerator = treeState.getVisiblePathsFrom
0N/A (initialPath);
0N/A int row = treeState.getRowForPath(initialPath);
0N/A int endY = paintBounds.y + paintBounds.height;
0N/A TreeModel treeModel = tree.getModel();
0N/A SynthContext cellContext = getContext(tree, Region.TREE_CELL);
0N/A
0N/A drawingCache.clear();
0N/A
0N/A setHashColor(context.getStyle().getColor(context,
0N/A ColorType.FOREGROUND));
0N/A
0N/A if (paintingEnumerator != null) {
0N/A // First pass, draw the rows
0N/A
0N/A boolean done = false;
0N/A boolean isExpanded;
0N/A boolean hasBeenExpanded;
0N/A boolean isLeaf;
0N/A Rectangle rowBounds = new Rectangle(0, 0, tree.getWidth(),0);
0N/A Rectangle bounds;
0N/A TreePath path;
0N/A TreeCellRenderer renderer = tree.getCellRenderer();
0N/A DefaultTreeCellRenderer dtcr = (renderer instanceof
0N/A DefaultTreeCellRenderer) ? (DefaultTreeCellRenderer)
0N/A renderer : null;
0N/A
0N/A configureRenderer(cellContext);
0N/A while (!done && paintingEnumerator.hasMoreElements()) {
0N/A path = (TreePath)paintingEnumerator.nextElement();
0N/A if (path != null) {
0N/A isLeaf = treeModel.isLeaf(path.getLastPathComponent());
0N/A if (isLeaf) {
0N/A isExpanded = hasBeenExpanded = false;
0N/A }
0N/A else {
0N/A isExpanded = treeState.getExpandedState(path);
0N/A hasBeenExpanded = tree.hasBeenExpanded(path);
0N/A }
0N/A bounds = getPathBounds(tree, path);
0N/A rowBounds.y = bounds.y;
0N/A rowBounds.height = bounds.height;
0N/A paintRow(renderer, dtcr, context, cellContext, g,
0N/A paintBounds, insets, bounds, rowBounds, path,
0N/A row, isExpanded, hasBeenExpanded, isLeaf);
0N/A if ((bounds.y + bounds.height) >= endY) {
0N/A done = true;
0N/A }
0N/A }
0N/A else {
0N/A done = true;
0N/A }
0N/A row++;
0N/A }
0N/A
0N/A // Draw the connecting lines and controls.
0N/A // Find each parent and have them draw a line to their last child
0N/A boolean rootVisible = tree.isRootVisible();
0N/A TreePath parentPath = initialPath;
0N/A parentPath = parentPath.getParentPath();
0N/A while (parentPath != null) {
0N/A paintVerticalPartOfLeg(g, paintBounds, insets, parentPath);
0N/A drawingCache.put(parentPath, Boolean.TRUE);
0N/A parentPath = parentPath.getParentPath();
0N/A }
0N/A done = false;
0N/A paintingEnumerator = treeState.getVisiblePathsFrom(initialPath);
0N/A while (!done && paintingEnumerator.hasMoreElements()) {
0N/A path = (TreePath)paintingEnumerator.nextElement();
0N/A if (path != null) {
0N/A isLeaf = treeModel.isLeaf(path.getLastPathComponent());
0N/A if (isLeaf) {
0N/A isExpanded = hasBeenExpanded = false;
0N/A }
0N/A else {
0N/A isExpanded = treeState.getExpandedState(path);
0N/A hasBeenExpanded = tree.hasBeenExpanded(path);
0N/A }
0N/A bounds = getPathBounds(tree, path);
0N/A // See if the vertical line to the parent has been drawn.
0N/A parentPath = path.getParentPath();
0N/A if (parentPath != null) {
0N/A if (drawingCache.get(parentPath) == null) {
0N/A paintVerticalPartOfLeg(g, paintBounds, insets,
0N/A parentPath);
0N/A drawingCache.put(parentPath, Boolean.TRUE);
0N/A }
0N/A paintHorizontalPartOfLeg(g,
0N/A paintBounds, insets, bounds,
0N/A path, row, isExpanded,
0N/A hasBeenExpanded, isLeaf);
0N/A }
0N/A else if (rootVisible && row == 0) {
0N/A paintHorizontalPartOfLeg(g,
0N/A paintBounds, insets, bounds,
0N/A path, row, isExpanded,
0N/A hasBeenExpanded, isLeaf);
0N/A }
0N/A if (shouldPaintExpandControl(path, row, isExpanded,
0N/A hasBeenExpanded, isLeaf)) {
0N/A paintExpandControl(g, paintBounds,
0N/A insets, bounds, path, row,
0N/A isExpanded, hasBeenExpanded,isLeaf);
0N/A }
0N/A if ((bounds.y + bounds.height) >= endY) {
0N/A done = true;
0N/A }
0N/A }
0N/A else {
0N/A done = true;
0N/A }
0N/A row++;
0N/A }
0N/A }
0N/A cellContext.dispose();
0N/A
0N/A paintDropLine(g);
0N/A
0N/A // Empty out the renderer pane, allowing renderers to be gc'ed.
0N/A rendererPane.removeAll();
4799N/A
4799N/A paintContext = null;
0N/A }
0N/A
0N/A private void configureRenderer(SynthContext context) {
0N/A TreeCellRenderer renderer = tree.getCellRenderer();
0N/A
0N/A if (renderer instanceof DefaultTreeCellRenderer) {
0N/A DefaultTreeCellRenderer r = (DefaultTreeCellRenderer)renderer;
0N/A SynthStyle style = context.getStyle();
0N/A
0N/A context.setComponentState(ENABLED | SELECTED);
0N/A Color color = r.getTextSelectionColor();
0N/A if (color == null || (color instanceof UIResource)) {
0N/A r.setTextSelectionColor(style.getColor(
0N/A context, ColorType.TEXT_FOREGROUND));
0N/A }
0N/A color = r.getBackgroundSelectionColor();
0N/A if (color == null || (color instanceof UIResource)) {
0N/A r.setBackgroundSelectionColor(style.getColor(
0N/A context, ColorType.TEXT_BACKGROUND));
0N/A }
0N/A
0N/A context.setComponentState(ENABLED);
0N/A color = r.getTextNonSelectionColor();
0N/A if (color == null || color instanceof UIResource) {
0N/A r.setTextNonSelectionColor(style.getColorForState(
0N/A context, ColorType.TEXT_FOREGROUND));
0N/A }
0N/A color = r.getBackgroundNonSelectionColor();
0N/A if (color == null || color instanceof UIResource) {
0N/A r.setBackgroundNonSelectionColor(style.getColorForState(
0N/A context, ColorType.TEXT_BACKGROUND));
0N/A }
0N/A }
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A protected void paintHorizontalPartOfLeg(Graphics g, Rectangle clipBounds,
0N/A Insets insets, Rectangle bounds,
0N/A TreePath path, int row,
0N/A boolean isExpanded,
0N/A boolean hasBeenExpanded, boolean
0N/A isLeaf) {
0N/A if (drawHorizontalLines) {
0N/A super.paintHorizontalPartOfLeg(g, clipBounds, insets, bounds,
0N/A path, row, isExpanded,
0N/A hasBeenExpanded, isLeaf);
0N/A }
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A protected void paintHorizontalLine(Graphics g, JComponent c, int y,
0N/A int left, int right) {
0N/A paintContext.getStyle().getGraphicsUtils(paintContext).drawLine(
0N/A paintContext, "Tree.horizontalLine", g, left, y, right, y, linesStyle);
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A protected void paintVerticalPartOfLeg(Graphics g,
0N/A Rectangle clipBounds, Insets insets,
0N/A TreePath path) {
0N/A if (drawVerticalLines) {
0N/A super.paintVerticalPartOfLeg(g, clipBounds, insets, path);
0N/A }
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A protected void paintVerticalLine(Graphics g, JComponent c, int x, int top,
0N/A int bottom) {
0N/A paintContext.getStyle().getGraphicsUtils(paintContext).drawLine(
0N/A paintContext, "Tree.verticalLine", g, x, top, x, bottom, linesStyle);
0N/A }
0N/A
1999N/A private void paintRow(TreeCellRenderer renderer,
0N/A DefaultTreeCellRenderer dtcr, SynthContext treeContext,
0N/A SynthContext cellContext, Graphics g, Rectangle clipBounds,
0N/A Insets insets, Rectangle bounds, Rectangle rowBounds,
0N/A TreePath path, int row, boolean isExpanded,
0N/A boolean hasBeenExpanded, boolean isLeaf) {
0N/A // Don't paint the renderer if editing this row.
0N/A boolean selected = tree.isRowSelected(row);
0N/A
614N/A JTree.DropLocation dropLocation = tree.getDropLocation();
0N/A boolean isDrop = dropLocation != null
0N/A && dropLocation.getChildIndex() == -1
0N/A && path == dropLocation.getPath();
0N/A
1173N/A int state = ENABLED;
0N/A if (selected || isDrop) {
1173N/A state |= SELECTED;
0N/A }
1173N/A
1999N/A if (tree.isFocusOwner() && row == getLeadSelectionRow()) {
1173N/A state |= FOCUSED;
0N/A }
1173N/A
1173N/A cellContext.setComponentState(state);
1173N/A
0N/A if (dtcr != null && (dtcr.getBorderSelectionColor() instanceof
0N/A UIResource)) {
0N/A dtcr.setBorderSelectionColor(style.getColor(
0N/A cellContext, ColorType.FOCUS));
0N/A }
0N/A SynthLookAndFeel.updateSubregion(cellContext, g, rowBounds);
0N/A cellContext.getPainter().paintTreeCellBackground(cellContext, g,
0N/A rowBounds.x, rowBounds.y, rowBounds.width,
0N/A rowBounds.height);
0N/A cellContext.getPainter().paintTreeCellBorder(cellContext, g,
0N/A rowBounds.x, rowBounds.y, rowBounds.width,
0N/A rowBounds.height);
0N/A if (editingComponent != null && editingRow == row) {
0N/A return;
0N/A }
0N/A
0N/A int leadIndex;
0N/A
0N/A if (tree.hasFocus()) {
1999N/A leadIndex = getLeadSelectionRow();
0N/A }
0N/A else {
0N/A leadIndex = -1;
0N/A }
0N/A
0N/A Component component = renderer.getTreeCellRendererComponent(
0N/A tree, path.getLastPathComponent(),
0N/A selected, isExpanded, isLeaf, row,
0N/A (leadIndex == row));
0N/A
0N/A rendererPane.paintComponent(g, component, tree, bounds.x, bounds.y,
0N/A bounds.width, bounds.height, true);
0N/A }
0N/A
0N/A private int findCenteredX(int x, int iconWidth) {
0N/A return tree.getComponentOrientation().isLeftToRight()
0N/A ? x - (int)Math.ceil(iconWidth / 2.0)
0N/A : x - (int)Math.floor(iconWidth / 2.0);
0N/A }
0N/A
1173N/A /**
1173N/A * @inheritDoc
1173N/A */
1173N/A @Override
1173N/A protected void paintExpandControl(Graphics g, Rectangle clipBounds,
1173N/A Insets insets, Rectangle bounds, TreePath path, int row,
1173N/A boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf) {
1173N/A //modify the paintContext's state to match the state for the row
1173N/A //this is a hack in that it requires knowledge of the subsequent
1173N/A //method calls. The point is, the context used in drawCentered
1173N/A //should reflect the state of the row, not of the tree.
1173N/A boolean isSelected = tree.getSelectionModel().isPathSelected(path);
1173N/A int state = paintContext.getComponentState();
1173N/A if (isSelected) {
1173N/A paintContext.setComponentState(state | SynthConstants.SELECTED);
1173N/A }
1173N/A super.paintExpandControl(g, clipBounds, insets, bounds, path, row,
1173N/A isExpanded, hasBeenExpanded, isLeaf);
1173N/A paintContext.setComponentState(state);
1173N/A }
1173N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A protected void drawCentered(Component c, Graphics graphics, Icon icon,
0N/A int x, int y) {
0N/A int w = SynthIcon.getIconWidth(icon, paintContext);
0N/A int h = SynthIcon.getIconHeight(icon, paintContext);
0N/A
0N/A SynthIcon.paintIcon(icon, paintContext, graphics,
0N/A findCenteredX(x, w),
0N/A y - h/2, w, h);
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1999N/A @Override
0N/A public void propertyChange(PropertyChangeEvent event) {
0N/A if (SynthLookAndFeel.shouldUpdateStyle(event)) {
0N/A updateStyle((JTree)event.getSource());
0N/A }
0N/A
0N/A if ("dropLocation" == event.getPropertyName()) {
0N/A JTree.DropLocation oldValue = (JTree.DropLocation)event.getOldValue();
0N/A repaintDropLocation(oldValue);
0N/A repaintDropLocation(tree.getDropLocation());
0N/A }
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1999N/A @Override
1999N/A protected void paintDropLine(Graphics g) {
1999N/A JTree.DropLocation loc = tree.getDropLocation();
1999N/A if (!isDropLine(loc)) {
1999N/A return;
1999N/A }
1999N/A
1999N/A Color c = (Color)style.get(paintContext, "Tree.dropLineColor");
1999N/A if (c != null) {
1999N/A g.setColor(c);
1999N/A Rectangle rect = getDropLineRect(loc);
1999N/A g.fillRect(rect.x, rect.y, rect.width, rect.height);
1999N/A }
1999N/A }
1999N/A
0N/A private void repaintDropLocation(JTree.DropLocation loc) {
0N/A if (loc == null) {
0N/A return;
0N/A }
0N/A
0N/A Rectangle r;
0N/A
0N/A if (isDropLine(loc)) {
0N/A r = getDropLineRect(loc);
0N/A } else {
0N/A r = tree.getPathBounds(loc.getPath());
0N/A if (r != null) {
0N/A r.x = 0;
0N/A r.width = tree.getWidth();
0N/A }
0N/A }
0N/A
0N/A if (r != null) {
0N/A tree.repaint(r);
0N/A }
0N/A }
0N/A
1999N/A /**
1999N/A * @inheritDoc
1999N/A */
1173N/A @Override
0N/A protected int getRowX(int row, int depth) {
0N/A return super.getRowX(row, depth) + padding;
0N/A }
0N/A
0N/A
0N/A private class SynthTreeCellRenderer extends DefaultTreeCellRenderer
0N/A implements UIResource {
0N/A SynthTreeCellRenderer() {
0N/A }
1173N/A
1173N/A @Override
0N/A public String getName() {
0N/A return "Tree.cellRenderer";
0N/A }
1173N/A
1173N/A @Override
0N/A public Component getTreeCellRendererComponent(JTree tree, Object value,
0N/A boolean sel,
0N/A boolean expanded,
0N/A boolean leaf, int row,
0N/A boolean hasFocus) {
0N/A if (!useTreeColors && (sel || hasFocus)) {
0N/A SynthLookAndFeel.setSelectedUI((SynthLabelUI)SynthLookAndFeel.
0N/A getUIOfType(getUI(), SynthLabelUI.class),
0N/A sel, hasFocus, tree.isEnabled(), false);
0N/A }
0N/A else {
0N/A SynthLookAndFeel.resetSelectedUI();
0N/A }
0N/A return super.getTreeCellRendererComponent(tree, value, sel,
0N/A expanded, leaf, row, hasFocus);
0N/A }
1173N/A
1173N/A @Override
0N/A public void paint(Graphics g) {
0N/A paintComponent(g);
0N/A if (hasFocus) {
0N/A SynthContext context = getContext(tree, Region.TREE_CELL);
0N/A
0N/A if (context.getStyle() == null) {
0N/A assert false: "SynthTreeCellRenderer is being used " +
0N/A "outside of UI that created it";
0N/A return;
0N/A }
0N/A int imageOffset = 0;
0N/A Icon currentI = getIcon();
0N/A
0N/A if(currentI != null && getText() != null) {
0N/A imageOffset = currentI.getIconWidth() +
0N/A Math.max(0, getIconTextGap() - 1);
0N/A }
0N/A if (selected) {
0N/A context.setComponentState(ENABLED | SELECTED);
0N/A }
0N/A else {
0N/A context.setComponentState(ENABLED);
0N/A }
0N/A if(getComponentOrientation().isLeftToRight()) {
0N/A context.getPainter().paintTreeCellFocus(context, g,
0N/A imageOffset, 0, getWidth() - imageOffset,
0N/A getHeight());
0N/A }
0N/A else {
0N/A context.getPainter().paintTreeCellFocus(context, g,
0N/A 0, 0, getWidth() - imageOffset, getHeight());
0N/A }
0N/A context.dispose();
0N/A }
0N/A SynthLookAndFeel.resetSelectedUI();
0N/A }
0N/A }
0N/A
0N/A
0N/A private static class SynthTreeCellEditor extends DefaultTreeCellEditor {
0N/A public SynthTreeCellEditor(JTree tree,
0N/A DefaultTreeCellRenderer renderer) {
0N/A super(tree, renderer);
0N/A setBorderSelectionColor(null);
0N/A }
0N/A
1173N/A @Override
0N/A protected TreeCellEditor createTreeCellEditor() {
0N/A JTextField tf = new JTextField() {
1173N/A @Override
0N/A public String getName() {
0N/A return "Tree.cellEditor";
0N/A }
0N/A };
0N/A DefaultCellEditor editor = new DefaultCellEditor(tf);
0N/A
0N/A // One click to edit.
0N/A editor.setClickCountToStart(1);
0N/A return editor;
0N/A }
0N/A }
0N/A
0N/A //
0N/A // BasicTreeUI directly uses expandIcon outside of the Synth methods.
0N/A // To get the correct context we return an instance of this that fetches
0N/A // the SynthContext as needed.
0N/A //
0N/A private class ExpandedIconWrapper extends SynthIcon {
0N/A public void paintIcon(SynthContext context, Graphics g, int x,
0N/A int y, int w, int h) {
0N/A if (context == null) {
0N/A context = getContext(tree);
0N/A SynthIcon.paintIcon(expandedIcon, context, g, x, y, w, h);
0N/A context.dispose();
0N/A }
0N/A else {
0N/A SynthIcon.paintIcon(expandedIcon, context, g, x, y, w, h);
0N/A }
0N/A }
0N/A
0N/A public int getIconWidth(SynthContext context) {
0N/A int width;
0N/A if (context == null) {
0N/A context = getContext(tree);
0N/A width = SynthIcon.getIconWidth(expandedIcon, context);
0N/A context.dispose();
0N/A }
0N/A else {
0N/A width = SynthIcon.getIconWidth(expandedIcon, context);
0N/A }
0N/A return width;
0N/A }
0N/A
0N/A public int getIconHeight(SynthContext context) {
0N/A int height;
0N/A if (context == null) {
0N/A context = getContext(tree);
0N/A height = SynthIcon.getIconHeight(expandedIcon, context);
0N/A context.dispose();
0N/A }
0N/A else {
0N/A height = SynthIcon.getIconHeight(expandedIcon, context);
0N/A }
0N/A return height;
0N/A }
0N/A }
0N/A}