summaryrefslogtreecommitdiff
path: root/javax/swing/plaf/metal
diff options
context:
space:
mode:
Diffstat (limited to 'javax/swing/plaf/metal')
-rw-r--r--javax/swing/plaf/metal/MetalButtonUI.java72
-rw-r--r--javax/swing/plaf/metal/MetalCheckBoxIcon.java11
-rw-r--r--javax/swing/plaf/metal/MetalLookAndFeel.java19
-rw-r--r--javax/swing/plaf/metal/MetalSplitPaneDivider.java281
-rw-r--r--javax/swing/plaf/metal/MetalTabbedPaneUI.java2
-rw-r--r--javax/swing/plaf/metal/MetalToolTipUI.java70
-rw-r--r--javax/swing/plaf/metal/MetalTreeUI.java122
7 files changed, 333 insertions, 244 deletions
diff --git a/javax/swing/plaf/metal/MetalButtonUI.java b/javax/swing/plaf/metal/MetalButtonUI.java
index 8addfc66c..be9607927 100644
--- a/javax/swing/plaf/metal/MetalButtonUI.java
+++ b/javax/swing/plaf/metal/MetalButtonUI.java
@@ -54,7 +54,6 @@ import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
-import javax.swing.plaf.basic.BasicButtonListener;
import javax.swing.plaf.basic.BasicButtonUI;
/**
@@ -66,24 +65,46 @@ public class MetalButtonUI
extends BasicButtonUI
{
- /** The color used to draw the focus rectangle around the text and/or icon. */
+ /**
+ * The shared button UI.
+ */
+ private static MetalButtonUI sharedUI;
+
+ /**
+ * The color used to draw the focus rectangle around the text and/or icon.
+ */
protected Color focusColor;
- /** The background color for the button when it is pressed. */
+ /**
+ * The background color for the button when it is pressed.
+ */
protected Color selectColor;
- /** The color for disabled button labels. */
+ /**
+ * The color for disabled button labels.
+ */
protected Color disabledTextColor;
/**
+ * Returns a UI delegate for the specified component.
+ *
+ * @param c the component (should be a subclass of {@link AbstractButton}).
+ *
+ * @return A new instance of <code>MetalButtonUI</code>.
+ */
+ public static ComponentUI createUI(JComponent c)
+ {
+ if (sharedUI == null)
+ sharedUI = new MetalButtonUI();
+ return sharedUI;
+ }
+
+ /**
* Creates a new instance.
*/
public MetalButtonUI()
{
super();
- focusColor = UIManager.getColor(getPropertyPrefix() + "focus");
- selectColor = UIManager.getColor(getPropertyPrefix() + "select");
- disabledTextColor = UIManager.getColor(getPropertyPrefix() + "disabledText");
}
/**
@@ -93,6 +114,7 @@ public class MetalButtonUI
*/
protected Color getFocusColor()
{
+ focusColor = UIManager.getColor(getPropertyPrefix() + "focus");
return focusColor;
}
@@ -103,6 +125,7 @@ public class MetalButtonUI
*/
protected Color getSelectColor()
{
+ selectColor = UIManager.getColor(getPropertyPrefix() + "select");
return selectColor;
}
@@ -113,22 +136,12 @@ public class MetalButtonUI
*/
protected Color getDisabledTextColor()
{
+ disabledTextColor = UIManager.getColor(getPropertyPrefix()
+ + "disabledText");
return disabledTextColor;
}
/**
- * Returns a UI delegate for the specified component.
- *
- * @param c the component (should be a subclass of {@link AbstractButton}).
- *
- * @return A new instance of <code>MetalButtonUI</code>.
- */
- public static ComponentUI createUI(JComponent c)
- {
- return new MetalButtonUI();
- }
-
- /**
* Installs the default settings for the specified button.
*
* @param button the button.
@@ -137,33 +150,20 @@ public class MetalButtonUI
*/
public void installDefaults(AbstractButton button)
{
+ // This is overridden to be public, for whatever reason.
super.installDefaults(button);
- button.setRolloverEnabled(UIManager.getBoolean(
- getPropertyPrefix() + "rollover"));
}
-
+
/**
* Removes the defaults added by {@link #installDefaults(AbstractButton)}.
*/
public void uninstallDefaults(AbstractButton button)
{
+ // This is overridden to be public, for whatever reason.
super.uninstallDefaults(button);
- button.setRolloverEnabled(false);
}
/**
- * Returns a button listener for the specified button.
- *
- * @param button the button.
- *
- * @return A button listener.
- */
- protected BasicButtonListener createButtonListener(AbstractButton button)
- {
- return new MetalButtonListener(button);
- }
-
- /**
* Paints the background of the button to indicate that it is in the
* "pressed" state.
*
@@ -175,7 +175,7 @@ public class MetalButtonUI
if (b.isContentAreaFilled())
{
Rectangle area = b.getVisibleRect();
- g.setColor(selectColor);
+ g.setColor(getSelectColor());
g.fillRect(area.x, area.y, area.width, area.height);
}
}
diff --git a/javax/swing/plaf/metal/MetalCheckBoxIcon.java b/javax/swing/plaf/metal/MetalCheckBoxIcon.java
index fb8280e44..30ee93162 100644
--- a/javax/swing/plaf/metal/MetalCheckBoxIcon.java
+++ b/javax/swing/plaf/metal/MetalCheckBoxIcon.java
@@ -1,5 +1,5 @@
/* MetalCheckBoxIcon.java -- An icon for JCheckBoxes in the Metal L&F
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -42,8 +42,8 @@ import java.awt.Component;
import java.awt.Graphics;
import java.io.Serializable;
+import javax.swing.AbstractButton;
import javax.swing.Icon;
-import javax.swing.JCheckBox;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.plaf.UIResource;
@@ -134,8 +134,9 @@ public class MetalCheckBoxIcon
MetalUtils.paintGradient(g, x, y, getIconWidth(), getIconHeight(),
SwingConstants.VERTICAL, "CheckBox.gradient");
border.paintBorder(c, g, x, y, getIconWidth(), getIconHeight());
- JCheckBox cb = (JCheckBox) c;
- if (cb.isSelected())
- drawCheck(c, g, x, y);
+
+ AbstractButton b = (AbstractButton) c;
+ if (b.isSelected())
+ drawCheck(b, g, x, y);
}
}
diff --git a/javax/swing/plaf/metal/MetalLookAndFeel.java b/javax/swing/plaf/metal/MetalLookAndFeel.java
index da16159c9..ff26aa232 100644
--- a/javax/swing/plaf/metal/MetalLookAndFeel.java
+++ b/javax/swing/plaf/metal/MetalLookAndFeel.java
@@ -38,6 +38,8 @@ exception statement from your version. */
package javax.swing.plaf.metal;
+import gnu.classpath.SystemProperties;
+
import java.awt.Color;
import java.awt.Font;
@@ -81,16 +83,15 @@ public class MetalLookAndFeel extends BasicLookAndFeel
*/
public MetalLookAndFeel()
{
- createDefaultTheme();
+ // Nothing to do here.
}
/**
- * Sets the current theme to a new instance of {@link OceanTheme}.
+ * Sets the current theme to a new instance of {@link DefaultMetalTheme}.
*/
protected void createDefaultTheme()
{
- if (theme == null)
- setCurrentTheme(new OceanTheme());
+ getCurrentTheme();
}
/**
@@ -149,6 +150,7 @@ public class MetalLookAndFeel extends BasicLookAndFeel
public UIDefaults getDefaults()
{
+ createDefaultTheme();
if (LAF_defaults == null)
{
LAF_defaults = super.getDefaults();
@@ -1354,7 +1356,14 @@ public class MetalLookAndFeel extends BasicLookAndFeel
public static MetalTheme getCurrentTheme()
{
if (theme == null)
- theme = new OceanTheme();
+ {
+ // swing.metalTheme property documented here:
+ // http://java.sun.com/j2se/1.5.0/docs/guide/swing/1.5/index.html
+ if ("steel".equals(SystemProperties.getProperty("swing.metalTheme")))
+ theme = new DefaultMetalTheme();
+ else
+ theme = new OceanTheme();
+ }
return theme;
}
diff --git a/javax/swing/plaf/metal/MetalSplitPaneDivider.java b/javax/swing/plaf/metal/MetalSplitPaneDivider.java
index 6081c355c..a3069daa9 100644
--- a/javax/swing/plaf/metal/MetalSplitPaneDivider.java
+++ b/javax/swing/plaf/metal/MetalSplitPaneDivider.java
@@ -38,18 +38,14 @@ exception statement from your version. */
package javax.swing.plaf.metal;
import java.awt.Color;
-import java.awt.Component;
-import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
-import java.awt.LayoutManager;
-import java.awt.Point;
+import java.awt.Insets;
+import javax.swing.JButton;
import javax.swing.JSplitPane;
-import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.Border;
-import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
/**
@@ -59,6 +55,143 @@ import javax.swing.plaf.basic.BasicSplitPaneDivider;
*/
class MetalSplitPaneDivider extends BasicSplitPaneDivider
{
+ /**
+ * The button pixel data, as indices into the colors array below.
+ * This is the version for 'left' buttons.
+ *
+ * This is slightly different from the icon in Sun's version, it is
+ * one pixel smaller and is more consistent with BUTTON_SPRITE_R.
+ */
+ static final byte[][] BUTTON_SPRITE_L = {{ 0, 0, 0, 2, 0, 0, 0, 0 },
+ { 0, 0, 2, 1, 1, 0, 0, 0 },
+ { 0, 2, 1, 1, 1, 1, 0, 0 },
+ { 2, 1, 1, 1, 1, 1, 1, 0 },
+ { 0, 3, 3, 3, 3, 3, 3, 3 }};
+
+ /**
+ * The button pixel data, as indices into the colors array below.
+ * This is the version for 'right' buttons.
+ */
+ static final byte[][] BUTTON_SPRITE_R = {{ 2, 2, 2, 2, 2, 2, 2, 2 },
+ { 0, 1, 1, 1, 1, 1, 1, 3 },
+ { 0, 0, 1, 1, 1, 1, 3, 0 },
+ { 0, 0, 0, 1, 1, 3, 0, 0 },
+ { 0, 0, 0, 0, 3, 0, 0, 0 }};
+
+ private class MetalOneTouchButton
+ extends JButton
+ {
+ /**
+ * Denotes a left button.
+ */
+ static final int LEFT = 0;
+
+ /**
+ * Denotes a right button.
+ */
+ static final int RIGHT = 1;
+
+ /**
+ * The colors for the button sprite.
+ */
+ private Color[] colors;
+
+ /**
+ * Either LEFT or RIGHT.
+ */
+ private int direction;
+
+ /**
+ * Creates a new instance.
+ *
+ * @param dir either LEFT or RIGHT
+ */
+ MetalOneTouchButton(int dir)
+ {
+ direction = dir;
+ colors = new Color[4];
+ }
+
+ /**
+ * Never allow borders.
+ */
+ public void setBorder(Border b)
+ {
+ }
+
+ /**
+ * Never allow focus traversal.
+ */
+ public boolean isFocusTraversable()
+ {
+ return false;
+ }
+
+ /**
+ * Paints the one touch button.
+ */
+ public void paint(Graphics g)
+ {
+ if (splitPane != null)
+ {
+ // Update colors here to reflect dynamic changes to the theme.
+ colors[0] = getBackground();
+ colors[1] = MetalLookAndFeel.getPrimaryControlDarkShadow();
+ colors[2] = MetalLookAndFeel.getPrimaryControlInfo();
+ colors[3] = MetalLookAndFeel.getPrimaryControlHighlight();
+
+ // Fill background.
+ g.setColor(getBackground());
+ g.fillRect(0, 0, getWidth(), getHeight());
+
+ // Pressed buttons have slightly different color mapping.
+ if (getModel().isPressed())
+ colors[1] = colors[2];
+
+ byte[][] sprite;
+ if (direction == LEFT)
+ sprite = BUTTON_SPRITE_L;
+ else
+ sprite = BUTTON_SPRITE_R;
+
+ if (orientation == JSplitPane.VERTICAL_SPLIT)
+ {
+ // Draw the sprite as it is.
+ for (int y = 0; y < sprite.length; y++)
+ {
+ byte[] line = sprite[y];
+ for (int x = 0; x < line.length; x++)
+ {
+ int c = line[x];
+ if (c != 0)
+ {
+ g.setColor(colors[c]);
+ g.fillRect(x + 1, y + 1, 1, 1);
+ }
+ }
+ }
+ }
+ else
+ {
+ // Draw the sprite with swapped X and Y axis.
+ for (int y = 0; y < sprite.length; y++)
+ {
+ byte[] line = sprite[y];
+ for (int x = 0; x < line.length; x++)
+ {
+ int c = line[x];
+ if (c != 0)
+ {
+ g.setColor(colors[c]);
+ g.fillRect(y + 1, x + 1, 1, 1);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
/** The dark color in the pattern. */
Color dark;
@@ -79,7 +212,6 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider
public MetalSplitPaneDivider(MetalSplitPaneUI ui, Color light, Color dark)
{
super(ui);
- setLayout(new MetalDividerLayout());
this.splitPane = super.splitPane;
this.orientation = super.orientation;
this.light = light;
@@ -106,126 +238,27 @@ class MetalSplitPaneDivider extends BasicSplitPaneDivider
if (border != null)
border.paintBorder(this, g, 0, 0, s.width, s.height);
- MetalUtils.fillMetalPattern(splitPane, g, 2, 2, s.width - 4, s.height - 4,
+ Insets i = getInsets();
+ MetalUtils.fillMetalPattern(splitPane, g, i.left + 2, i.top + 2,
+ s.width - i.left - i.right - 4,
+ s.height - i.top - i.bottom - 4,
light, dark);
- if (splitPane.isOneTouchExpandable())
- {
- ((BasicArrowButton) rightButton).paint(g);
- ((BasicArrowButton) leftButton).paint(g);
- }
+ super.paint(g);
}
-
- /**
- * This helper class acts as the Layout Manager for the divider.
- */
- public class MetalDividerLayout implements LayoutManager
- {
- /** The right button. */
- BasicArrowButton rb;
-
- /** The left button. */
- BasicArrowButton lb;
-
- /**
- * Creates a new DividerLayout object.
- */
- public MetalDividerLayout()
- {
- // Nothing to do here
- }
-
- /**
- * This method is called when a Component is added.
- *
- * @param string The constraints string.
- * @param c The Component to add.
- */
- public void addLayoutComponent(String string, Component c)
- {
- // Nothing to do here, constraints are set depending on
- // orientation in layoutContainer
- }
-
- /**
- * This method is called to lay out the container.
- *
- * @param c The container to lay out.
- */
- public void layoutContainer(Container c)
- {
- // The only components we care about setting up are the
- // one touch buttons.
- if (splitPane.isOneTouchExpandable())
- {
- if (c.getComponentCount() == 2)
- {
- Component c1 = c.getComponent(0);
- Component c2 = c.getComponent(1);
- if ((c1 instanceof BasicArrowButton)
- && (c2 instanceof BasicArrowButton))
- {
- lb = (BasicArrowButton) c1;
- rb = (BasicArrowButton) c2;
- }
- }
- if (rb != null && lb != null)
- {
- Point p = getLocation();
- lb.setSize(lb.getPreferredSize());
- rb.setSize(rb.getPreferredSize());
- lb.setLocation(p.x, p.y);
-
- if (orientation == JSplitPane.HORIZONTAL_SPLIT)
- {
- rb.setDirection(SwingConstants.EAST);
- lb.setDirection(SwingConstants.WEST);
- rb.setLocation(p.x, p.y + lb.getHeight());
- }
- else
- {
- rb.setDirection(SwingConstants.SOUTH);
- lb.setDirection(SwingConstants.NORTH);
- rb.setLocation(p.x + lb.getWidth(), p.y);
- }
- }
- }
- }
-
- /**
- * This method returns the minimum layout size.
- *
- * @param c The container to calculate for.
- *
- * @return The minimum layout size.
- */
- public Dimension minimumLayoutSize(Container c)
- {
- return preferredLayoutSize(c);
- }
- /**
- * This method returns the preferred layout size.
- *
- * @param c The container to calculate for.
- *
- * @return The preferred layout size.
- */
- public Dimension preferredLayoutSize(Container c)
- {
- int dividerSize = getDividerSize();
- return new Dimension(dividerSize, dividerSize);
- }
+ protected JButton createLeftOneTouchButton()
+ {
+ JButton b = new MetalOneTouchButton(MetalOneTouchButton.LEFT);
+ b.setMinimumSize(new Dimension(ONE_TOUCH_SIZE, ONE_TOUCH_SIZE));
+ b.setRequestFocusEnabled(false);
+ return b;
+ }
- /**
- * This method is called when a component is removed.
- *
- * @param c The component to remove.
- */
- public void removeLayoutComponent(Component c)
- {
- // Nothing to do here. If buttons are removed
- // they will not be layed out when layoutContainer is
- // called.
- }
+ protected JButton createRightOneTouchButton()
+ {
+ JButton b = new MetalOneTouchButton(MetalOneTouchButton.RIGHT);
+ b.setMinimumSize(new Dimension(ONE_TOUCH_SIZE, ONE_TOUCH_SIZE));
+ b.setRequestFocusEnabled(false);
+ return b;
}
}
diff --git a/javax/swing/plaf/metal/MetalTabbedPaneUI.java b/javax/swing/plaf/metal/MetalTabbedPaneUI.java
index 20135fc85..53eaa3cac 100644
--- a/javax/swing/plaf/metal/MetalTabbedPaneUI.java
+++ b/javax/swing/plaf/metal/MetalTabbedPaneUI.java
@@ -1159,7 +1159,7 @@ public class MetalTabbedPaneUI extends BasicTabbedPaneUI
g.drawLine(x + 1, y + 1, x + 1, rect.y + 1);
if (rect.y + rect.height < y + h - 2)
{
- g.drawLine(x + y, rect.y + rect.height + 1, x + 1, y + h + 2);
+ g.drawLine(x + 1, rect.y + rect.height + 1, x + 1, y + h + 2);
}
}
}
diff --git a/javax/swing/plaf/metal/MetalToolTipUI.java b/javax/swing/plaf/metal/MetalToolTipUI.java
index d1040347f..6647cc02d 100644
--- a/javax/swing/plaf/metal/MetalToolTipUI.java
+++ b/javax/swing/plaf/metal/MetalToolTipUI.java
@@ -43,9 +43,6 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
-import java.awt.Insets;
-import java.awt.Rectangle;
-import java.awt.Toolkit;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
@@ -54,8 +51,6 @@ import javax.swing.JComponent;
import javax.swing.JMenuItem;
import javax.swing.JToolTip;
import javax.swing.KeyStroke;
-import javax.swing.SwingConstants;
-import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
@@ -192,32 +187,14 @@ public class MetalToolTipUI
*/
public Dimension getPreferredSize(JComponent c)
{
- if (isAcceleratorHidden())
- return super.getPreferredSize(c);
- else
+ Dimension d = super.getPreferredSize(c);
+ String acc = getAcceleratorString();
+ if (acc != null && ! acc.equals(""))
{
- Insets insets = c.getInsets();
- JToolTip tt = (JToolTip) c;
- String tipText = tt.getTipText();
- if (tipText != null)
- {
- FontMetrics fm = c.getFontMetrics(c.getFont());
- int prefH = fm.getHeight() + insets.top + insets.bottom;
- int prefW = fm.stringWidth(tipText) + insets.left + insets.right;
-
- // this seems to be the first opportunity we have to get the
- // accelerator string from the component (if it has one)
- acceleratorString = fetchAcceleratorString(c);
- if (acceleratorString != null)
- {
- prefW += padSpaceBetweenStrings;
- fm = c.getFontMetrics(acceleratorFont);
- prefW += fm.stringWidth(acceleratorString);
- }
- return new Dimension(prefW, prefH);
- }
- else return new Dimension(0, 0);
+ FontMetrics fm = c.getFontMetrics(c.getFont());
+ d.width += fm.stringWidth(acc);
}
+ return d;
}
/**
@@ -228,39 +205,8 @@ public class MetalToolTipUI
*/
public void paint(Graphics g, JComponent c)
{
- JToolTip tip = (JToolTip) c;
-
- String text = tip.getTipText();
- Toolkit t = tip.getToolkit();
- if (text == null)
- return;
-
- Rectangle vr = new Rectangle();
- vr = SwingUtilities.calculateInnerArea(tip, vr);
- Rectangle ir = new Rectangle();
- Rectangle tr = new Rectangle();
- FontMetrics fm = t.getFontMetrics(tip.getFont());
- int ascent = fm.getAscent();
- SwingUtilities.layoutCompoundLabel(tip, fm, text, null,
- SwingConstants.CENTER, SwingConstants.LEFT,
- SwingConstants.CENTER, SwingConstants.CENTER, vr, ir, tr, 0);
- Color saved = g.getColor();
- g.setColor(Color.BLACK);
-
- g.drawString(text, vr.x, vr.y + ascent);
-
- // paint accelerator
- if (acceleratorString != null)
- {
- g.setFont(acceleratorFont);
- g.setColor(acceleratorForeground);
- fm = t.getFontMetrics(acceleratorFont);
- int width = fm.stringWidth(acceleratorString);
- g.drawString(acceleratorString, vr.x + vr.width - width
- - padSpaceBetweenStrings / 2, vr.y + vr.height - fm.getDescent());
- }
-
- g.setColor(saved);
+ super.paint(g, c);
+ // Somehow paint accelerator. Keep care for possible HTML rendering.
}
/**
diff --git a/javax/swing/plaf/metal/MetalTreeUI.java b/javax/swing/plaf/metal/MetalTreeUI.java
index 3ea37c82f..ed1e5b4d8 100644
--- a/javax/swing/plaf/metal/MetalTreeUI.java
+++ b/javax/swing/plaf/metal/MetalTreeUI.java
@@ -38,14 +38,15 @@ exception statement from your version. */
package javax.swing.plaf.metal;
-import gnu.classpath.NotImplementedException;
-
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
import javax.swing.JTree;
+import javax.swing.UIManager;
import javax.swing.tree.TreePath;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTreeUI;
@@ -56,6 +57,68 @@ import javax.swing.plaf.basic.BasicTreeUI;
public class MetalTreeUI extends BasicTreeUI
{
/**
+ * Listens for property changes of the line style and updates the
+ * internal setting.
+ */
+ private class LineStyleListener
+ implements PropertyChangeListener
+ {
+
+ public void propertyChange(PropertyChangeEvent e)
+ {
+ if (e.getPropertyName().equals(LINE_STYLE_PROPERTY))
+ decodeLineStyle(e.getNewValue());
+ }
+
+ }
+
+ /**
+ * The key to the lineStyle client property.
+ */
+ private static final String LINE_STYLE_PROPERTY = "JTree.lineStyle";
+
+ /**
+ * The property value indicating no line style.
+ */
+ private static final String LINE_STYLE_VALUE_NONE = "None";
+
+ /**
+ * The property value indicating angled line style.
+ */
+ private static final String LINE_STYLE_VALUE_ANGLED = "Angled";
+
+ /**
+ * The property value indicating horizontal line style.
+ */
+ private static final String LINE_STYLE_VALUE_HORIZONTAL = "Horizontal";
+
+ /**
+ * The line style for None.
+ */
+ private static final int LINE_STYLE_NONE = 0;
+
+ /**
+ * The line style for Angled.
+ */
+ private static final int LINE_STYLE_ANGLED = 1;
+
+ /**
+ * The line style for Horizontal.
+ */
+ private static final int LINE_STYLE_HORIZONTAL = 2;
+
+ /**
+ * The current line style.
+ */
+ private int lineStyle;
+
+ /**
+ * Listens for changes on the line style property and updates the
+ * internal settings.
+ */
+ private PropertyChangeListener lineStyleListener;
+
+ /**
* Constructs a new instance of <code>MetalTreeUI</code>.
*/
public MetalTreeUI()
@@ -103,8 +166,13 @@ public class MetalTreeUI extends BasicTreeUI
*/
public void installUI(JComponent c)
{
- // TODO: What to do here, if anything?
super.installUI(c);
+
+ Object lineStyleProp = c.getClientProperty(LINE_STYLE_PROPERTY);
+ decodeLineStyle(lineStyleProp);
+ if (lineStyleListener == null)
+ lineStyleListener = new LineStyleListener();
+ c.addPropertyChangeListener(lineStyleListener);
}
/**
@@ -124,8 +192,10 @@ public class MetalTreeUI extends BasicTreeUI
*/
public void uninstallUI(JComponent c)
{
- // TODO: What to do here?
super.uninstallUI(c);
+ if (lineStyleListener != null)
+ c.removePropertyChangeListener(lineStyleListener);
+ lineStyleListener = null;
}
/**
@@ -135,9 +205,15 @@ public class MetalTreeUI extends BasicTreeUI
* @param lineStyleFlag - String representation
*/
protected void decodeLineStyle(Object lineStyleFlag)
- throws NotImplementedException
{
- // FIXME: not implemented
+ if (lineStyleFlag == null || lineStyleFlag.equals(LINE_STYLE_VALUE_ANGLED))
+ lineStyle = LINE_STYLE_ANGLED;
+ else if (lineStyleFlag.equals(LINE_STYLE_VALUE_HORIZONTAL))
+ lineStyle = LINE_STYLE_HORIZONTAL;
+ else if (lineStyleFlag.equals(LINE_STYLE_VALUE_NONE))
+ lineStyle = LINE_STYLE_NONE;
+ else
+ lineStyle = LINE_STYLE_ANGLED;
}
/**
@@ -170,6 +246,9 @@ public class MetalTreeUI extends BasicTreeUI
// Calls BasicTreeUI's paint since it takes care of painting all
// types of icons.
super.paint(g, c);
+
+ if (lineStyle == LINE_STYLE_HORIZONTAL)
+ paintHorizontalSeparators(g, c);
}
/**
@@ -179,9 +258,28 @@ public class MetalTreeUI extends BasicTreeUI
* @param c - the current component to draw
*/
protected void paintHorizontalSeparators(Graphics g, JComponent c)
- throws NotImplementedException
{
- // FIXME: not implemented
+ g.setColor(UIManager.getColor("Tree.line"));
+ Rectangle clip = g.getClipBounds();
+ int row0 = getRowForPath(tree, getClosestPathForLocation(tree, 0, clip.y));
+ int row1 =
+ getRowForPath(tree, getClosestPathForLocation(tree, 0,
+ clip.y + clip.height - 1));
+ if (row0 >= 0 && row1 >= 0)
+ {
+ for (int i = row0; i <= row1; i++)
+ {
+ TreePath p = getPathForRow(tree, i);
+ if (p != null && p.getPathCount() == 2)
+ {
+ Rectangle r = getPathBounds(tree, getPathForRow(tree, i));
+ if (r != null)
+ {
+ g.drawLine(clip.x, r.y, clip.x + clip.width, r.y);
+ }
+ }
+ }
+ }
}
@@ -197,7 +295,8 @@ public class MetalTreeUI extends BasicTreeUI
protected void paintVerticalPartOfLeg(Graphics g, Rectangle clipBounds,
Insets insets, TreePath path)
{
- super.paintVerticalPartOfLeg(g, clipBounds, insets, path);
+ if (lineStyle == LINE_STYLE_ANGLED)
+ super.paintVerticalPartOfLeg(g, clipBounds, insets, path);
}
/**
@@ -211,7 +310,8 @@ public class MetalTreeUI extends BasicTreeUI
boolean isExpanded, boolean hasBeenExpanded,
boolean isLeaf)
{
- super.paintHorizontalPartOfLeg(g, clipBounds, insets, bounds, path, row,
- isExpanded, hasBeenExpanded, isLeaf);
+ if (lineStyle == LINE_STYLE_ANGLED)
+ super.paintHorizontalPartOfLeg(g, clipBounds, insets, bounds, path, row,
+ isExpanded, hasBeenExpanded, isLeaf);
}
}