This fixes painting of selected cells in a JTree and should be slightly
faster too.
2006-09-28 Roman Kennke <[EMAIL PROTECTED]>
* javax/swing/tree/DefaultTreeCellRenderer.java
(DefaultTreeCellRenderer): Fetch drawsFocusBorderAroundIcon
property from UIManager.
(paint): Rewritten to use super's implementation and only paint
background and focus indicator before.
(paintFocus): New helper method.
(getXOffset): New helper method.
/Roman
Index: javax/swing/tree/DefaultTreeCellRenderer.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/tree/DefaultTreeCellRenderer.java,v
retrieving revision 1.27
diff -u -1 -5 -r1.27 DefaultTreeCellRenderer.java
--- javax/swing/tree/DefaultTreeCellRenderer.java 16 Aug 2006 19:28:49 -0000 1.27
+++ javax/swing/tree/DefaultTreeCellRenderer.java 28 Sep 2006 10:28:36 -0000
@@ -65,31 +65,31 @@
extends JLabel
implements TreeCellRenderer
{
/**
* A flag indicating the current selection status.
*/
protected boolean selected;
/**
* A flag indicating the current focus status.
*/
protected boolean hasFocus;
/**
- * drawsFocusBorderAroundIcon // FIXME: is this used?
+ * 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)
*/
@@ -140,30 +140,32 @@
/**
* Creates a new tree cell renderer with defaults appropriate for the
* current [EMAIL PROTECTED] 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
* [EMAIL PROTECTED] LookAndFeel} using the key <code>Tree.openIcon</code>.
*
* @return The default icon.
*/
public Icon getDefaultOpenIcon()
{
return UIManager.getIcon("Tree.openIcon");
}
/**
@@ -487,72 +489,90 @@
*
* @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)
{
- // paint background
- Rectangle vr = new Rectangle();
- Rectangle ir = new Rectangle();
- Rectangle tr = new Rectangle();
-
- Insets insets = new Insets(0, 0, 0, 0);
- Border border = UIManager.getBorder("Tree.selectionBorder");
- if (border != null)
- insets = border.getBorderInsets(this);
-
- FontMetrics fm = getToolkit().getFontMetrics(getFont());
- SwingUtilities.layoutCompoundLabel((JLabel) this, fm, getText(),
- getIcon(), getVerticalAlignment(),
- getHorizontalAlignment(),
- getVerticalTextPosition(),
- getHorizontalTextPosition(), vr, ir, tr,
- getIconTextGap());
-
- // Reusing one rectangle.
- Rectangle bounds = getBounds(ir);
-
- bounds.x = tr.x - insets.left;
- bounds.width = tr.width + insets.left + insets.right;
-
- g.setColor(super.getBackground());
- g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
+ // 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)
+ {
+ Icon i = getIcon();
+ xOffset = getXOffset();
+ g.setColor(bgColor);
+ g.fillRect(xOffset, 0, getWidth() - xOffset, getHeight());
+ }
- super.paint(g);
-
- // Paint the border of the focused element only (lead selection)
if (hasFocus)
{
- Color b = getBorderSelectionColor();
- if (b != null)
- {
- g.setColor(b);
- g.drawRect(bounds.x, bounds.y, bounds.width, bounds.height - 1);
- }
+ 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()