| /* DefaultTreeCellRenderer.java | |
| Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc. | |
| This file is part of GNU Classpath. | |
| GNU Classpath is free software; you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation; either version 2, or (at your option) | |
| any later version. | |
| GNU Classpath is distributed in the hope that it will be useful, but | |
| WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| General Public License for more details. | |
| You should have received a copy of the GNU General Public License | |
| along with GNU Classpath; see the file COPYING. If not, write to the | |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | |
| 02110-1301 USA. | |
| Linking this library statically or dynamically with other modules is | |
| making a combined work based on this library. Thus, the terms and | |
| conditions of the GNU General Public License cover the whole | |
| combination. | |
| As a special exception, the copyright holders of this library give you | |
| permission to link this library with independent modules to produce an | |
| executable, regardless of the license terms of these independent | |
| modules, and to copy and distribute the resulting executable under | |
| terms of your choice, provided that you also meet, for each linked | |
| independent module, the terms and conditions of the license of that | |
| module. An independent module is a module which is not derived from | |
| or based on this library. If you modify this library, you may extend | |
| this exception to your version of the library, but you are not | |
| obligated to do so. If you do not wish to do so, delete this | |
| exception statement from your version. */ | |
| package javax.swing.tree; | |
| import java.awt.Color; | |
| import java.awt.Component; | |
| import java.awt.Dimension; | |
| import java.awt.Font; | |
| import java.awt.Graphics; | |
| import java.awt.Rectangle; | |
| import javax.swing.Icon; | |
| import javax.swing.JLabel; | |
| import javax.swing.JTree; | |
| import javax.swing.LookAndFeel; | |
| import javax.swing.UIManager; | |
| import javax.swing.plaf.UIResource; | |
| /** | |
| * A default implementation of the {@link TreeCellRenderer} interface. | |
| * | |
| * @author Andrew Selkirk | |
| */ | |
| public class DefaultTreeCellRenderer | |
| extends JLabel | |
| implements TreeCellRenderer | |
| { | |
| /** | |
| * A flag indicating the current selection status. | |
| */ | |
| protected boolean selected; | |
| /** | |
| * A flag indicating the current focus status. | |
| */ | |
| protected boolean hasFocus; | |
| /** | |
| * Indicates if the focus border is also drawn around the icon. | |
| */ | |
| private boolean drawsFocusBorderAroundIcon; | |
| /** | |
| * The icon used to represent non-leaf nodes that are closed. | |
| * | |
| * @see #setClosedIcon(Icon) | |
| */ | |
| protected transient Icon closedIcon; | |
| /** | |
| * The icon used to represent leaf nodes. | |
| * | |
| * @see #setLeafIcon(Icon) | |
| */ | |
| protected transient Icon leafIcon; | |
| /** | |
| * The icon used to represent non-leaf nodes that are open. | |
| * | |
| * @see #setOpenIcon(Icon) | |
| */ | |
| protected transient Icon openIcon; | |
| /** | |
| * The color used for text in selected cells. | |
| * | |
| * @see #setTextSelectionColor(Color) | |
| */ | |
| protected Color textSelectionColor; | |
| /** | |
| * The color used for text in non-selected cells. | |
| * | |
| * @see #setTextNonSelectionColor(Color) | |
| */ | |
| protected Color textNonSelectionColor; | |
| /** | |
| * The background color for selected cells. | |
| * | |
| * @see #setBackgroundSelectionColor(Color) | |
| */ | |
| protected Color backgroundSelectionColor; | |
| /** | |
| * The background color for non-selected cells. | |
| * | |
| * @see #setBackgroundNonSelectionColor(Color) | |
| */ | |
| protected Color backgroundNonSelectionColor; | |
| /** | |
| * The border color for selected tree cells. | |
| * | |
| * @see #setBorderSelectionColor(Color) | |
| */ | |
| protected Color borderSelectionColor; | |
| /** | |
| * Creates a new tree cell renderer with defaults appropriate for the | |
| * current {@link LookAndFeel}. | |
| */ | |
| public DefaultTreeCellRenderer() | |
| { | |
| setLeafIcon(getDefaultLeafIcon()); | |
| setOpenIcon(getDefaultOpenIcon()); | |
| setClosedIcon(getDefaultClosedIcon()); | |
| setTextNonSelectionColor(UIManager.getColor("Tree.textForeground")); | |
| setTextSelectionColor(UIManager.getColor("Tree.selectionForeground")); | |
| setBackgroundNonSelectionColor(UIManager.getColor("Tree.textBackground")); | |
| setBackgroundSelectionColor(UIManager.getColor("Tree.selectionBackground")); | |
| setBorderSelectionColor(UIManager.getColor("Tree.selectionBorderColor")); | |
| Object val = UIManager.get("Tree.drawsFocusBorderAroundIcon"); | |
| drawsFocusBorderAroundIcon = val != null && ((Boolean) val).booleanValue(); | |
| } | |
| /** | |
| * Returns the default icon for non-leaf tree cells that are open (expanded). | |
| * The icon is fetched from the defaults table for the current | |
| * {@link LookAndFeel} using the key <code>Tree.openIcon</code>. | |
| * | |
| * @return The default icon. | |
| */ | |
| public Icon getDefaultOpenIcon() | |
| { | |
| return UIManager.getIcon("Tree.openIcon"); | |
| } | |
| /** | |
| * Returns the default icon for non-leaf tree cells that are closed (not | |
| * expanded). The icon is fetched from the defaults table for the current | |
| * {@link LookAndFeel} using the key <code>Tree.closedIcon</code>. | |
| * | |
| * @return The default icon. | |
| */ | |
| public Icon getDefaultClosedIcon() | |
| { | |
| return UIManager.getIcon("Tree.closedIcon"); | |
| } | |
| /** | |
| * Returns the default icon for leaf tree cells. The icon is fetched from | |
| * the defaults table for the current {@link LookAndFeel} using the key | |
| * <code>Tree.leafIcon</code>. | |
| * | |
| * @return The default icon. | |
| */ | |
| public Icon getDefaultLeafIcon() | |
| { | |
| return UIManager.getIcon("Tree.leafIcon"); | |
| } | |
| /** | |
| * Sets the icon to be displayed for non-leaf nodes that are open (expanded). | |
| * Set this to <code>null</code> if no icon is required. | |
| * | |
| * @param icon the icon (<code>null</code> permitted). | |
| * | |
| * @see #getOpenIcon() | |
| */ | |
| public void setOpenIcon(Icon icon) | |
| { | |
| openIcon = icon; | |
| } | |
| /** | |
| * Returns the icon displayed for non-leaf nodes that are open (expanded). | |
| * The default value is initialised from the {@link LookAndFeel}. | |
| * | |
| * @return The open icon (possibly <code>null</code>). | |
| * | |
| * @see #setOpenIcon(Icon) | |
| */ | |
| public Icon getOpenIcon() | |
| { | |
| return openIcon; | |
| } | |
| /** | |
| * Sets the icon to be displayed for non-leaf nodes that are closed. Set | |
| * this to <code>null</code> if no icon is required. | |
| * | |
| * @param icon the icon (<code>null</code> permitted). | |
| * | |
| * @see #getClosedIcon() | |
| */ | |
| public void setClosedIcon(Icon icon) | |
| { | |
| closedIcon = icon; | |
| } | |
| /** | |
| * Returns the icon displayed for non-leaf nodes that are closed. The | |
| * default value is initialised from the {@link LookAndFeel}. | |
| * | |
| * @return The closed icon (possibly <code>null</code>). | |
| * | |
| * @see #setClosedIcon(Icon) | |
| */ | |
| public Icon getClosedIcon() | |
| { | |
| return closedIcon; | |
| } | |
| /** | |
| * Sets the icon to be displayed for leaf nodes. Set this to | |
| * <code>null</code> if no icon is required. | |
| * | |
| * @param icon the icon (<code>null</code> permitted). | |
| * | |
| * @see #getLeafIcon() | |
| */ | |
| public void setLeafIcon(Icon icon) | |
| { | |
| leafIcon = icon; | |
| } | |
| /** | |
| * Returns the icon displayed for leaf nodes. The default value is | |
| * initialised from the {@link LookAndFeel}. | |
| * | |
| * @return The leaf icon (possibly <code>null</code>). | |
| * | |
| * @see #setLeafIcon(Icon) | |
| */ | |
| public Icon getLeafIcon() | |
| { | |
| return leafIcon; | |
| } | |
| /** | |
| * Sets the text color for tree cells that are selected. | |
| * | |
| * @param c the color (<code>null</code> permitted). | |
| * | |
| * @see #getTextSelectionColor() | |
| */ | |
| public void setTextSelectionColor(Color c) | |
| { | |
| textSelectionColor = c; | |
| } | |
| /** | |
| * Returns the text color for tree cells that are selected. | |
| * The default value is obtained from the {@link LookAndFeel} defaults | |
| * table using the key <code>Tree.selectionForeground</code>. | |
| * | |
| * @return The text color for tree cells that are selected. | |
| * | |
| * @see #setTextSelectionColor(Color) | |
| */ | |
| public Color getTextSelectionColor() | |
| { | |
| return textSelectionColor; | |
| } | |
| /** | |
| * Sets the text color for tree cells that are not selected. | |
| * | |
| * @param c the color (<code>null</code> permitted). | |
| * | |
| * @see #getTextNonSelectionColor() | |
| */ | |
| public void setTextNonSelectionColor(Color c) | |
| { | |
| textNonSelectionColor = c; | |
| } | |
| /** | |
| * Returns the text color for tree cells that are not selected. | |
| * The default value is obtained from the {@link LookAndFeel} defaults | |
| * table using the key <code>Tree.selectionForeground</code>. | |
| * | |
| * @return The background color for tree cells that are not selected. | |
| * | |
| * @see #setTextgroundNonSelectionColor(Color) | |
| */ | |
| public Color getTextNonSelectionColor() | |
| { | |
| return textNonSelectionColor; | |
| } | |
| /** | |
| * Sets the background color for tree cells that are selected. | |
| * | |
| * @param c the color (<code>null</code> permitted). | |
| * | |
| * @see #getBackgroundSelectionColor() | |
| */ | |
| public void setBackgroundSelectionColor(Color c) | |
| { | |
| backgroundSelectionColor = c; | |
| } | |
| /** | |
| * Returns the background color for tree cells that are selected. | |
| * The default value is obtained from the {@link LookAndFeel} defaults | |
| * table using the key <code>Tree.selectionBackground</code>. | |
| * | |
| * @return The background color for tree cells that are selected. | |
| * | |
| * @see #setBackgroundSelectionColor(Color) | |
| */ | |
| public Color getBackgroundSelectionColor() | |
| { | |
| return backgroundSelectionColor; | |
| } | |
| /** | |
| * Sets the background color for tree cells that are not selected. | |
| * | |
| * @param c the color (<code>null</code> permitted). | |
| * | |
| * @see #getBackgroundNonSelectionColor() | |
| */ | |
| public void setBackgroundNonSelectionColor(Color c) | |
| { | |
| backgroundNonSelectionColor = c; | |
| } | |
| /** | |
| * Returns the background color for tree cells that are not selected. | |
| * The default value is obtained from the {@link LookAndFeel} defaults | |
| * table using the key <code>Tree.textBackground</code>. | |
| * | |
| * @return The background color for tree cells that are not selected. | |
| * | |
| * @see #setBackgroundNonSelectionColor(Color) | |
| */ | |
| public Color getBackgroundNonSelectionColor() | |
| { | |
| return backgroundNonSelectionColor; | |
| } | |
| /** | |
| * Sets the border color for tree cells that are selected. | |
| * | |
| * @param c the color (<code>null</code> permitted). | |
| * | |
| * @see #getBorderSelectionColor() | |
| */ | |
| public void setBorderSelectionColor(Color c) | |
| { | |
| borderSelectionColor = c; | |
| } | |
| /** | |
| * Returns the border color for tree cells that are selected. | |
| * The default value is obtained from the {@link LookAndFeel} defaults | |
| * table using the key <code>Tree.selectionBorderColor</code>. | |
| * | |
| * @return The border color for tree cells that are selected. | |
| * | |
| * @see #setBorderSelectionColor(Color) | |
| */ | |
| public Color getBorderSelectionColor() | |
| { | |
| return borderSelectionColor; | |
| } | |
| /** | |
| * Sets the font. | |
| * | |
| * @param f the font. | |
| * | |
| * @see #getFont() | |
| */ | |
| public void setFont(Font f) | |
| { | |
| if (f != null && f instanceof UIResource) | |
| f = null; | |
| super.setFont(f); | |
| } | |
| /** | |
| * Sets the background color. | |
| * | |
| * @param c the color. | |
| */ | |
| public void setBackground(Color c) | |
| { | |
| if (c != null && c instanceof UIResource) | |
| c = null; | |
| super.setBackground(c); | |
| } | |
| /** | |
| * Returns a component (in fact <code>this</code>) that can be used to | |
| * render a tree cell with the specified state. | |
| * | |
| * @param tree the tree that the cell belongs to. | |
| * @param val the cell value. | |
| * @param selected indicates whether or not the cell is selected. | |
| * @param expanded indicates whether or not the cell is expanded. | |
| * @param leaf indicates whether or not the cell is a leaf in the tree. | |
| * @param row the row index. | |
| * @param hasFocus indicates whether or not the cell has the focus. | |
| * | |
| * @return <code>this</code>. | |
| */ | |
| public Component getTreeCellRendererComponent(JTree tree, Object val, | |
| boolean selected, | |
| boolean expanded, boolean leaf, | |
| int row, boolean hasFocus) | |
| { | |
| if (leaf) | |
| setIcon(getLeafIcon()); | |
| else if (expanded) | |
| setIcon(getOpenIcon()); | |
| else | |
| setIcon(getClosedIcon()); | |
| setText(val.toString()); | |
| this.selected = selected; | |
| this.hasFocus = hasFocus; | |
| setHorizontalAlignment(LEFT); | |
| setOpaque(false); | |
| setVerticalAlignment(CENTER); | |
| setEnabled(true); | |
| super.setFont(UIManager.getFont("Tree.font")); | |
| if (selected) | |
| { | |
| super.setBackground(getBackgroundSelectionColor()); | |
| setForeground(getTextSelectionColor()); | |
| if (hasFocus) | |
| setBorderSelectionColor(UIManager.getLookAndFeelDefaults(). | |
| getColor("Tree.selectionBorderColor")); | |
| else | |
| setBorderSelectionColor(null); | |
| } | |
| else | |
| { | |
| super.setBackground(getBackgroundNonSelectionColor()); | |
| setForeground(getTextNonSelectionColor()); | |
| setBorderSelectionColor(null); | |
| } | |
| return this; | |
| } | |
| /** | |
| * Returns the current font. | |
| * | |
| * @return The current font. | |
| * | |
| * @see #setFont(Font) | |
| */ | |
| public Font getFont() | |
| { | |
| return super.getFont(); | |
| } | |
| /** | |
| * Paints the value. The background is filled based on selected. | |
| * | |
| * @param g the graphics device. | |
| */ | |
| public void paint(Graphics g) | |
| { | |
| // Determine background color. | |
| Color bgColor; | |
| if (selected) | |
| bgColor = getBackgroundSelectionColor(); | |
| else | |
| { | |
| bgColor = getBackgroundNonSelectionColor(); | |
| if (bgColor == null) | |
| bgColor = getBackground(); | |
| } | |
| // Paint background. | |
| int xOffset = -1; | |
| if (bgColor != null) | |
| { | |
| xOffset = getXOffset(); | |
| g.setColor(bgColor); | |
| g.fillRect(xOffset, 0, getWidth() - xOffset, getHeight()); | |
| } | |
| if (hasFocus) | |
| { | |
| if (drawsFocusBorderAroundIcon) | |
| xOffset = 0; | |
| else if (xOffset == -1) | |
| xOffset = getXOffset(); | |
| paintFocus(g, xOffset, 0, getWidth() - xOffset, getHeight()); | |
| } | |
| super.paint(g); | |
| } | |
| /** | |
| * Paints the focus indicator. | |
| */ | |
| private void paintFocus(Graphics g, int x, int y, int w, int h) | |
| { | |
| Color col = getBorderSelectionColor(); | |
| if (col != null) | |
| { | |
| g.setColor(col); | |
| g.drawRect(x, y, w - 1, h - 1); | |
| } | |
| } | |
| /** | |
| * Determines the X offset of the label that is caused by | |
| * the icon. | |
| * | |
| * @return the X offset of the label | |
| */ | |
| private int getXOffset() | |
| { | |
| Icon i = getIcon(); | |
| int offs = 0; | |
| if (i != null && getText() != null) | |
| offs = i.getIconWidth() + Math.max(0, getIconTextGap() - 1); | |
| return offs; | |
| } | |
| /** | |
| * Returns the preferred size of the cell. | |
| * | |
| * @return The preferred size of the cell. | |
| */ | |
| public Dimension getPreferredSize() | |
| { | |
| Dimension size = super.getPreferredSize(); | |
| size.width += 3; | |
| return size; | |
| } | |
| /** | |
| * For performance reasons, this method is overridden to do nothing. | |
| */ | |
| public void validate() | |
| { | |
| // Overridden for performance reasons. | |
| } | |
| /** | |
| * For performance reasons, this method is overridden to do nothing. | |
| */ | |
| public void revalidate() | |
| { | |
| // Overridden for performance reasons. | |
| } | |
| /** | |
| * For performance reasons, this method is overridden to do nothing. | |
| * | |
| * @param tm ignored | |
| * @param x coordinate of the region to mark as dirty | |
| * @param y coordinate of the region to mark as dirty | |
| * @param width dimension of the region to mark as dirty | |
| * @param height dimension of the region to mark as dirty | |
| */ | |
| public void repaint(long tm, int x, int y, int width, int height) | |
| { | |
| // Overridden for performance reasons. | |
| } | |
| /** | |
| * For performance reasons, this method is overridden to do nothing. | |
| * | |
| * @param area the area to repaint. | |
| */ | |
| public void repaint(Rectangle area) | |
| { | |
| // Overridden for performance reasons. | |
| } | |
| /** | |
| * For performance reasons, this method is overridden to do nothing. | |
| * | |
| * @param name the property name. | |
| * @param oldValue the old value. | |
| * @param newValue the new value. | |
| */ | |
| protected void firePropertyChange(String name, Object oldValue, | |
| Object newValue) | |
| { | |
| // Overridden for performance reasons. | |
| } | |
| /** | |
| * For performance reasons, this method is overridden to do nothing. | |
| * | |
| * @param name the property name. | |
| * @param oldValue the old value. | |
| * @param newValue the new value. | |
| */ | |
| public void firePropertyChange(String name, byte oldValue, byte newValue) | |
| { | |
| // Overridden for performance reasons. | |
| } | |
| /** | |
| * For performance reasons, this method is overridden to do nothing. | |
| * | |
| * @param name the property name. | |
| * @param oldValue the old value. | |
| * @param newValue the new value. | |
| */ | |
| public void firePropertyChange(String name, char oldValue, char newValue) | |
| { | |
| // Overridden for performance reasons. | |
| } | |
| /** | |
| * For performance reasons, this method is overridden to do nothing. | |
| * | |
| * @param name the property name. | |
| * @param oldValue the old value. | |
| * @param newValue the new value. | |
| */ | |
| public void firePropertyChange(String name, short oldValue, short newValue) | |
| { | |
| // Overridden for performance reasons. | |
| } | |
| /** | |
| * For performance reasons, this method is overridden to do nothing. | |
| * | |
| * @param name the property name. | |
| * @param oldValue the old value. | |
| * @param newValue the new value. | |
| */ | |
| public void firePropertyChange(String name, int oldValue, int newValue) | |
| { | |
| // Overridden for performance reasons. | |
| } | |
| /** | |
| * For performance reasons, this method is overridden to do nothing. | |
| * | |
| * @param name the property name. | |
| * @param oldValue the old value. | |
| * @param newValue the new value. | |
| */ | |
| public void firePropertyChange(String name, long oldValue, long newValue) | |
| { | |
| // Overridden for performance reasons. | |
| } | |
| /** | |
| * For performance reasons, this method is overridden to do nothing. | |
| * | |
| * @param name the property name. | |
| * @param oldValue the old value. | |
| * @param newValue the new value. | |
| */ | |
| public void firePropertyChange(String name, float oldValue, float newValue) | |
| { | |
| // Overridden for performance reasons. | |
| } | |
| /** | |
| * For performance reasons, this method is overridden to do nothing. | |
| * | |
| * @param name the property name. | |
| * @param oldValue the old value. | |
| * @param newValue the new value. | |
| */ | |
| public void firePropertyChange(String name, double oldValue, double newValue) | |
| { | |
| // Overridden for performance reasons. | |
| } | |
| /** | |
| * For performance reasons, this method is overridden to do nothing. | |
| * | |
| * @param name the property name. | |
| * @param oldValue the old value. | |
| * @param newValue the new value. | |
| */ | |
| public void firePropertyChange(String name, boolean oldValue, | |
| boolean newValue) | |
| { | |
| // Overridden for performance reasons. | |
| } | |
| } |