classpath-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cp-patches] FYI: MetalScrollBarUI and MetalScrollButton


From: David Gilbert
Subject: [cp-patches] FYI: MetalScrollBarUI and MetalScrollButton
Date: Thu, 08 Sep 2005 10:08:20 +0000
User-agent: Mozilla Thunderbird 1.0.6 (X11/20050728)

I committed this patch, which implements most of the scroll bar UI delegate for the MetalLookAndFeel. The new MetalScrollButton class paints its own border (which varies depending on the direction of the button, whether the button is enabled, and whether or not the scrollbar that the button belongs to is free standing). I tried to use a custom Border to do this, but couldn't get it to work, even using the UI delegate on top of Sun's BasicLookAndFeel, so in the end resorted to just painting the border in the paint() method. If someone can find a way to make it work with a real Border, then feel free to change the code. For now, it seems to work reasonably well.

There's also a small fix in the MetalUtils class to make the "metal" pattern move smoothly for vertical scroll bars.

Here's the ChangeLog entry:

2005-09-08  David Gilbert  <address@hidden>

        * javax/swing/plaf/basic/BasicLookAndFeel.java
        (initComponentDefaults): added 'ScrollBar.width' default,
        * javax/swing/plaf/metal/MetalScrollBarUI.java
        (MetalScrollBarPropertyChangeHandler): new class,
        (FREE_STANDING_PROP): added,
        (MIN_THUMB_SIZE): modified dimensions,
        (increaseButton): new field,
        (decreaseButton): new field,
        (scrollBarWidth): new field,
        (isFreeStanding): new field,
        (createUI): just return a new instance,
        (installDefaults): implemented,
        (createPropertyChangeListener): implemented,
        (createDecreaseButton): implemented,
        (createIncreaseButton): implemented,
        (paintTrack): implemented,
        (paintTrackHorizontal): new private method,
        (paintTrackVertical): new private method,
        (paintThumb): updated,
        * javax/swing/plaf/metal/MetalScrollButton.java: implemented,
        * javax/swing/plaf/metal/MetalUtils.java
        (fillMetalPattern): modified alternating color calculation.

Regards,

Dave Gilbert
Index: javax/swing/plaf/basic/BasicLookAndFeel.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java,v
retrieving revision 1.51
diff -u -r1.51 BasicLookAndFeel.java
--- javax/swing/plaf/basic/BasicLookAndFeel.java        2 Sep 2005 18:03:25 
-0000       1.51
+++ javax/swing/plaf/basic/BasicLookAndFeel.java        8 Sep 2005 08:52:12 
-0000
@@ -742,6 +742,7 @@
       "ScrollBar.thumbShadow", new ColorUIResource(shadow),
       "ScrollBar.track", new ColorUIResource(light),
       "ScrollBar.trackHighlight", new ColorUIResource(shadow),
+      "ScrollBar.width", new Integer(16),
       "ScrollPane.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] {
         "PAGE_UP", "scrollUp",
         "KP_LEFT", "unitScrollLeft",
Index: javax/swing/plaf/metal/MetalScrollBarUI.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/metal/MetalScrollBarUI.java,v
retrieving revision 1.5
diff -u -r1.5 MetalScrollBarUI.java
--- javax/swing/plaf/metal/MetalScrollBarUI.java        2 Jul 2005 20:32:51 
-0000       1.5
+++ javax/swing/plaf/metal/MetalScrollBarUI.java        8 Sep 2005 08:52:12 
-0000
@@ -38,28 +38,87 @@
 
 package javax.swing.plaf.metal;
 
+import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.Rectangle;
-import java.util.HashMap;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 
+import javax.swing.JButton;
 import javax.swing.JComponent;
+import javax.swing.JScrollBar;
 import javax.swing.UIDefaults;
 import javax.swing.UIManager;
 import javax.swing.plaf.ComponentUI;
 import javax.swing.plaf.basic.BasicScrollBarUI;
 
+/**
+ * A UI delegate for the address@hidden JScrollBar} component.
+ */
 public class MetalScrollBarUI
   extends BasicScrollBarUI
 {
+  
+  /**
+   * A property change handler for the UI delegate that monitors for
+   * changes to the "JScrollBar.isFreeStanding" property, and updates
+   * the buttons and track rendering as appropriate.
+   */
+  class MetalScrollBarPropertyChangeHandler 
+    extends BasicScrollBarUI.PropertyChangeHandler
+  {
+    /**
+     * Creates a new handler.
+     * 
+     * @see #createPropertyChangeListener()
+     */
+    public MetalScrollBarPropertyChangeHandler()
+    {
+    }
+    
+    /**
+     * Handles a property change event.  If the event name is
+     * <code>JSlider.isFreeStanding</code>, this method updates the 
+     * delegate, otherwise the event is passed up to the super class.
+     * 
+     * @param e  the property change event.
+     */
+    public void propertyChange(PropertyChangeEvent e)
+    {
+      if (e.getPropertyName().equals(FREE_STANDING_PROP))
+        {
+          Boolean prop = (Boolean) e.getNewValue();
+          isFreeStanding = (prop == null ? true : prop.booleanValue());
+          increaseButton.setFreeStanding(isFreeStanding);
+          decreaseButton.setFreeStanding(isFreeStanding);
+        }
+    }
+  }
+  
+  /** The name for the 'free standing' property. */
+  public static final String FREE_STANDING_PROP = "JScrollBar.isFreeStanding";
 
   /** The minimum thumb size */
-  private static final Dimension MIN_THUMB_SIZE = new Dimension(18, 18);
-
-  // FIXME: maybe replace by a Map of instances when this becomes stateful
-  /** The shared UI instance for JScrollBars. */
-  private static HashMap instances = null;
+  private static final Dimension MIN_THUMB_SIZE = new Dimension(17, 17);
 
+  /** The button that increases the value in the scroll bar. */
+  protected MetalScrollButton increaseButton;
+  
+  /** The button that decreases the value in the scroll bar. */
+  protected MetalScrollButton decreaseButton;
+  
+  /** The scroll bar width. */
+  protected int scrollBarWidth;
+  
+  /** 
+   * A flag that indicates whether the scroll bar is "free standing", which 
+   * means it has complete borders and can be used anywhere in the UI.  A 
+   * scroll bar which is not free standing has borders missing from one
+   * side, and relies on being part of another container with its own borders
+   * to look right visually. */
+  protected boolean isFreeStanding;
+  
   /**
    * Constructs a new instance of MetalScrollBarUI.
    */
@@ -77,20 +136,166 @@
    */
   public static ComponentUI createUI(JComponent component)
   {
-    if (instances == null)
-      instances = new HashMap();
+    return new MetalScrollBarUI();
+  }
+
+  /**
+   * Installs the defaults.
+   */
+  protected void installDefaults()
+  {    
+    // need to initialise isFreeStanding before calling the super class, 
+    // so that the value is set when createIncreaseButton() and 
+    // createDecreaseButton() are called (unless there is somewhere earlier
+    // that we can do this).
+    Boolean prop = (Boolean) scrollbar.getClientProperty(FREE_STANDING_PROP);
+    isFreeStanding = (prop == null ? true : prop.booleanValue());
+    super.installDefaults();
+  }
+    
+  /**
+   * Creates a property change listener for the delegate to use.  This
+   * overrides the method to provide a custom listener for the 
+   * address@hidden MetalLookAndFeel} that can handle the 
+   * <code>JScrollBar.isFreeStanding</code> property.
+   * 
+   * @return A property change listener.
+   */
+  protected PropertyChangeListener createPropertyChangeListener()
+  {
+    return new MetalScrollBarPropertyChangeHandler();
+  }
+  
+  /**
+   * Creates a new button to use as the control at the lower end of the
+   * address@hidden JScrollBar}.
+   * 
+   * @param orientation  the orientation of the button (address@hidden #NORTH},
+   *                     address@hidden #SOUTH}, address@hidden #EAST} or 
address@hidden #WEST}).
+   * 
+   * @return The button.
+   */
+  protected JButton createDecreaseButton(int orientation)
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    scrollBarWidth = defaults.getInt("ScrollBar.width");
+    return new MetalScrollButton(orientation, scrollBarWidth, isFreeStanding);
+  }
 
-    Object o = instances.get(component);
-    MetalScrollBarUI instance;
-    if (o == null)
+  /**
+   * Creates a new button to use as the control at the upper end of the
+   * address@hidden JScrollBar}.
+   * 
+   * @param orientation  the orientation of the button (address@hidden #NORTH},
+   *                     address@hidden #SOUTH}, address@hidden #EAST} or 
address@hidden #WEST}).
+   * 
+   * @return The button.
+   */
+  protected JButton createIncreaseButton(int orientation)
+  {
+    UIDefaults defaults = UIManager.getLookAndFeelDefaults();
+    scrollBarWidth = defaults.getInt("ScrollBar.width");
+    return new MetalScrollButton(orientation, scrollBarWidth, isFreeStanding);
+  }
+  
+  /**
+   * Paints the track for the scrollbar.
+   * 
+   * @param g  the graphics device.
+   * @param c  the component.
+   * @param trackBounds  the track bounds.
+   */
+  protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds)
+  {
+    g.setColor(MetalLookAndFeel.getControl());
+    g.fillRect(trackBounds.x, trackBounds.y, trackBounds.width, 
+            trackBounds.height);
+    if (scrollbar.getOrientation() == HORIZONTAL) 
+      paintTrackHorizontal(g, c, trackBounds.x, trackBounds.y, 
+          trackBounds.width, trackBounds.height);
+    else 
+      paintTrackVertical(g, c, trackBounds.x, trackBounds.y, 
+          trackBounds.width, trackBounds.height);
+    
+  }
+  
+  /**
+   * Paints the track for a horizontal scrollbar.
+   * 
+   * @param g  the graphics device.
+   * @param c  the component.
+   * @param x  the x-coordinate for the track bounds.
+   * @param y  the y-coordinate for the track bounds.
+   * @param w  the width for the track bounds.
+   * @param h  the height for the track bounds.
+   */
+  private void paintTrackHorizontal(Graphics g, JComponent c, 
+      int x, int y, int w, int h)
+  {
+    if (c.isEnabled())
       {
-       instance = new MetalScrollBarUI();
-       instances.put(component, instance);
+        g.setColor(MetalLookAndFeel.getControlDarkShadow());
+        g.drawLine(x, y, x, y + h - 1);
+        g.drawLine(x, y, x + w - 1, y);
+        g.drawLine(x + w - 1, y, x + w - 1, y + h - 1);
+        
+        g.setColor(MetalLookAndFeel.getControlShadow());
+        g.drawLine(x + 1, y + 1, x + 1, y + h - 1);
+        g.drawLine(x + 1, y + 1, x + w - 2, y + 1);
+        
+        if (isFreeStanding) 
+          {
+            g.setColor(MetalLookAndFeel.getControlDarkShadow());
+            g.drawLine(x, y + h - 2, x + w - 1, y + h - 2);
+            g.setColor(MetalLookAndFeel.getControlShadow());
+            g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
+          }
       }
     else
-      instance = (MetalScrollBarUI) o;
-
-    return instance;
+      {
+        g.setColor(MetalLookAndFeel.getControlDisabled());
+        g.drawRect(x, y, w - 1, h - 1);
+      }
+  }
+    
+  /**
+   * Paints the track for a vertical scrollbar.
+   * 
+   * @param g  the graphics device.
+   * @param c  the component.
+   * @param x  the x-coordinate for the track bounds.
+   * @param y  the y-coordinate for the track bounds.
+   * @param w  the width for the track bounds.
+   * @param h  the height for the track bounds.
+   */
+  protected void paintTrackVertical(Graphics g, JComponent c, 
+      int x, int y, int w, int h)
+  {
+    if (c.isEnabled())
+      {
+        g.setColor(MetalLookAndFeel.getControlDarkShadow());
+        g.drawLine(x, y, x, y + h - 1);
+        g.drawLine(x, y, x + w - 1, y);
+        g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);
+        
+        g.setColor(MetalLookAndFeel.getControlShadow());
+        g.drawLine(x + 1, y + 1, x + w - 1, y + 1);
+        g.drawLine(x + 1, y + 1, x + 1, y + h - 2);
+        g.drawLine(x + 1, y + h - 2, x + w - 1, y + h - 2);
+        
+        if (isFreeStanding) 
+          {
+            g.setColor(MetalLookAndFeel.getControlDarkShadow());
+            g.drawLine(x + w - 2, y, x + w - 2, y + h - 1);
+            g.setColor(MetalLookAndFeel.getControlHighlight());
+            g.drawLine(x + w - 1, y, x + w - 1, y + h - 1);
+          }
+      }
+    else
+      {
+        g.setColor(MetalLookAndFeel.getControlDisabled());
+        g.drawRect(x, y, w - 1, h - 1);
+      }
   }
 
   /**
@@ -102,15 +307,26 @@
    */
   protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds)
   {
+    // a disabled scrollbar has no thumb in the metal look and feel
+    if (!c.isEnabled())
+      return;
+    
     // first we fill the background
     g.setColor(thumbColor);
     g.fillRect(thumbBounds.x, thumbBounds.y, thumbBounds.width,
                thumbBounds.height);
 
     // draw the outer dark line
-    g.setColor(thumbDarkShadowColor);
-    g.drawRect(thumbBounds.x, thumbBounds.y, thumbBounds.width - 1,
-               thumbBounds.height - 1);
+    int hAdj = 1;
+    int wAdj = 1;
+    if (scrollbar.getOrientation() == HORIZONTAL)
+      hAdj++;
+    else
+      wAdj++;
+    
+    g.setColor(new Color(102, 102, 153));
+    g.drawRect(thumbBounds.x, thumbBounds.y, thumbBounds.width - wAdj,
+               thumbBounds.height - hAdj);
 
     // draw the inner light line
     g.setColor(thumbHighlightColor);
@@ -131,7 +347,7 @@
     // draw the pattern
     MetalUtils.fillMetalPattern(g, thumbBounds.x + 3, thumbBounds.y + 3,
                                 thumbBounds.width - 6, thumbBounds.height - 6,
-                                thumbHighlightColor, thumbDarkShadowColor);
+                                thumbHighlightColor, new Color(102, 102, 153));
   }
 
   /**
@@ -143,4 +359,6 @@
   {
     return MIN_THUMB_SIZE;
   }
+  
 }
+
Index: javax/swing/plaf/metal/MetalScrollButton.java
===================================================================
RCS file: javax/swing/plaf/metal/MetalScrollButton.java
diff -N javax/swing/plaf/metal/MetalScrollButton.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/swing/plaf/metal/MetalScrollButton.java       8 Sep 2005 08:52:13 
-0000
@@ -0,0 +1,482 @@
+/* MetalScrollButton.java
+   Copyright (C) 2005 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.plaf.metal;
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+
+import javax.swing.SwingUtilities;
+import javax.swing.plaf.basic.BasicArrowButton;
+
+/**
+ * A button used by the address@hidden MetalScrollBarUI}.  The button 
appearance
+ * varies according to the button direction, whether or not it is part of a 
+ * "free standing" scroll bar, and the current state of the button. 
+ */
+public class MetalScrollButton extends BasicArrowButton 
+{
+  
+  /** 
+   * The maximum size for buttons.
+   * @see #getMaximumSize()
+   */
+  private static Dimension maximumSize;     
+  
+  /** The width of the button. */
+  private int buttonWidth;
+  
+  /** 
+   * A flag that indicates whether the button is part of a free standing 
+   * scroll bar.  This affects how the border is drawn.
+   */
+  private boolean freeStanding;
+  
+  /**
+   * Creates a new button.
+   * 
+   * @param direction  the direction (this should be one of address@hidden 
#NORTH}, 
+   *                   address@hidden #SOUTH}, address@hidden #EAST} and 
address@hidden #WEST}, but 
+   *                   this is not enforced).
+   * @param width  the button width.
+   * @param freeStanding  a flag indicating whether the scroll button is free
+   *                      standing or not.
+   */
+  public MetalScrollButton(int direction, int width, boolean freeStanding)
+  {
+    super(direction);
+    buttonWidth = width;
+    this.freeStanding = freeStanding;
+  }
+  
+  /**
+   * Returns the button width.
+   * 
+   * @return The button width.
+   */
+  public int getButtonWidth()
+  {
+    return buttonWidth;   
+  }
+
+  /**
+   * Sets the free standing flag.  This controls how the button border is
+   * drawn.
+   * 
+   * @param freeStanding  the new value of the flag.
+   */
+  public void setFreeStanding(boolean freeStanding)
+  {
+    this.freeStanding = freeStanding;
+  }
+  
+  /**
+   * Paints the button.
+   * 
+   * @param g  the graphics device.
+   */
+  public void paint(Graphics g)
+  {
+    Rectangle bounds = SwingUtilities.getLocalBounds(this);
+
+    // fill the background
+    if (getModel().isPressed())
+      g.setColor(MetalLookAndFeel.getControlShadow());
+    else
+      g.setColor(MetalLookAndFeel.getControl());
+    g.fillRect(0, 0, bounds.width, bounds.height);
+    
+    paintArrow(g, bounds.width, bounds.height);
+    
+    // paint a border manually - I tried using a real (custom) Border
+    // but couldn't get it to stay set for the button, something was 
+    // overwriting it...
+    if (freeStanding) 
+      {
+        if (direction == WEST)
+          paintWestBorderFreeStanding(g, bounds.width, bounds.height);        
+        else if (direction == EAST)
+          paintEastBorderFreeStanding(g, bounds.width, bounds.height);
+        else if (direction == SOUTH)
+          paintSouthBorderFreeStanding(g, bounds.width, bounds.height);
+        else // asume NORTH
+          paintNorthBorderFreeStanding(g, bounds.width, bounds.height);
+      }
+    else
+      {
+        if (direction == WEST)
+          paintWestBorder(g, bounds.width, bounds.height);        
+        else if (direction == EAST)
+          paintEastBorder(g, bounds.width, bounds.height);
+        else if (direction == SOUTH)
+          paintSouthBorder(g, bounds.width, bounds.height);
+        else // asume NORTH
+          paintNorthBorder(g, bounds.width, bounds.height);
+      }
+  }
+  
+  private void paintArrow(Graphics g, int w, int h)
+  {
+    if (isEnabled())
+      g.setColor(MetalLookAndFeel.getBlack());
+    else
+      g.setColor(MetalLookAndFeel.getControlDisabled());
+    
+    if (direction == SOUTH)
+      {
+        int x = w / 2;
+        int y = h / 2 + 2;
+        for (int i = 1; i < 5; i++)
+          g.drawLine(x - i, y - i, x + i - 1, y - i);
+      }
+    else if (direction == EAST)
+      {
+        int x = w / 2 + 2;
+        int y = h / 2;
+        for (int i = 1; i < 5; i++)
+          g.drawLine(x - i, y - i, x - i, y + i - 1);
+      }
+    else if (direction == WEST)
+      {
+        int x = w / 2 - 3;
+        int y = h / 2;
+        for (int i = 1; i < 5; i++)
+          g.drawLine(x + i, y - i, x + i, y + i - 1);        
+      }
+    else // assume NORTH
+      {
+        int x = w / 2;
+        int y = h / 2 - 3;
+        for (int i = 1; i < 5; i++)
+          g.drawLine(x - i, y + i, x + i - 1, y + i);
+      }
+  }
+  /**
+   * Paints the border for a button with a address@hidden #NORTH} direction 
that
+   * belongs to a free standing scroll bar.
+   * 
+   * @param g  the graphics device.
+   * @param w  the button width.
+   * @param h  the button height.
+   */
+  private void paintNorthBorderFreeStanding(Graphics g, int w, int h) 
+  {
+    if (isEnabled())
+      {
+        g.setColor(MetalLookAndFeel.getControlDarkShadow());
+        g.drawLine(0, 0, w - 2, 0);
+        g.drawLine(0, 0, 0, h - 1);
+        g.drawLine(2, h - 1, w - 2, h - 1);
+        g.drawLine(w - 2, 2, w - 2, h - 1);
+        
+        g.setColor(MetalLookAndFeel.getControlHighlight());
+        g.drawLine(1, 1, 1, h - 1);
+        g.drawLine(1, 1, w - 1, 1);
+        g.drawLine(w - 1, 1, w - 1, h - 1);
+      
+        g.setColor(MetalLookAndFeel.getControl());
+        g.drawLine(1, h - 1, 1, h - 1);
+        g.drawLine(w - 1, 1, w - 1, 1);
+      }
+    else
+      {
+        g.setColor(MetalLookAndFeel.getControlDisabled());
+        g.drawLine(0, 0, w - 1, 0);
+        g.drawLine(w - 1, 0, w - 1, h - 1);
+        g.drawLine(0, 0, 0, h - 1);
+      }
+  }
+  
+  /**
+   * Paints the border for a button with a address@hidden #SOUTH} direction 
that
+   * belongs to a free standing scroll bar.
+   * 
+   * @param g  the graphics device.
+   * @param w  the button width.
+   * @param h  the button height.
+   */
+  private void paintSouthBorderFreeStanding(Graphics g, int w, int h)
+  {
+    if (isEnabled())
+      {
+        g.setColor(MetalLookAndFeel.getControlDarkShadow());
+        g.drawLine(0, 0, w - 2, 0);
+        g.drawLine(0, 0, 0, h - 1);
+        g.drawLine(2, h - 1, w - 2, h - 1);
+        g.drawLine(w - 2, 2, w - 2, h - 1);
+        
+        g.setColor(MetalLookAndFeel.getControlHighlight());
+        g.drawLine(1, 1, 1, h - 1);
+        g.drawLine(1, 1, w - 1, 1);
+        g.drawLine(w - 1, 1, w - 1, h - 1);
+      
+        g.setColor(MetalLookAndFeel.getControl());
+        g.drawLine(1, h - 1, 1, h - 1);
+        g.drawLine(w - 1, 1, w - 1, 1);
+      }
+    else
+      {
+        g.setColor(MetalLookAndFeel.getControlDisabled());
+        g.drawLine(0, h - 1, w - 1, h - 1);
+        g.drawLine(w - 1, 0, w - 1, h - 1);
+        g.drawLine(0, 0, 0, h - 1);
+      }
+  }
+  
+  /**
+   * Paints the border for a button with an address@hidden #EAST} direction 
that
+   * belongs to a free standing scroll bar.
+   * 
+   * @param g  the graphics device.
+   * @param w  the button width.
+   * @param h  the button height.
+   */
+  private void paintEastBorderFreeStanding(Graphics g, int w, int h)
+  {
+    if (isEnabled())
+      {
+        g.setColor(MetalLookAndFeel.getControlDarkShadow());
+        g.drawLine(0, 0, w - 2, 0);
+        g.drawLine(w - 2, 0, w - 2, h - 2);
+        g.drawLine(0, h - 2, w - 2, h - 2);
+        
+        g.setColor(MetalLookAndFeel.getControlHighlight());
+        g.drawLine(0, 1, w - 1, 1);
+        g.drawLine(w - 1, 1, w - 1, h - 1);
+        g.drawLine(0, h - 1, w - 1, h - 1);
+      
+        g.setColor(MetalLookAndFeel.getControl());
+        g.drawLine(w - 2, 1, w - 2, 1);
+      }
+    else
+      {
+        g.setColor(MetalLookAndFeel.getControlDisabled());
+        g.drawLine(0, 0, w - 1, 0);
+        g.drawLine(w - 1, 0, w - 1, h - 1);
+        g.drawLine(0, h - 1, w - 1, h - 1);
+      }
+  }
+  
+  /**
+   * Paints the border for a button with a address@hidden #WEST} direction that
+   * belongs to a free standing scroll bar.
+   * 
+   * @param g  the graphics device.
+   * @param w  the button width.
+   * @param h  the button height.
+   */
+  private void paintWestBorderFreeStanding(Graphics g, int w, int h)
+  {
+    if (isEnabled())
+      {
+        g.setColor(MetalLookAndFeel.getControlDarkShadow());
+        g.drawLine(0, 0, w - 1, 0);
+        g.drawLine(0, 0, 0, h - 2);
+        g.drawLine(0, h - 2, w - 1, h - 2);
+        
+        g.setColor(MetalLookAndFeel.getControlHighlight());
+        g.drawLine(1, 1, w - 1, 1);
+        g.drawLine(1, 1, 1, h - 1);
+        g.drawLine(1, h - 1, w - 1, h - 1);
+      
+        g.setColor(MetalLookAndFeel.getControl());
+        g.drawLine(1, h - 2, 1, h - 2);
+      }
+    else
+      {
+        g.setColor(MetalLookAndFeel.getControlDisabled());
+        g.drawLine(0, 0, w - 1, 0);
+        g.drawLine(0, 0, 0, h - 1);
+        g.drawLine(0, h - 1, w - 1, h - 1);
+      }
+  }
+  
+  /**
+   * Paints the border for a button with a address@hidden #NORTH} direction 
that
+   * belongs to a scroll bar that is not free standing.
+   * 
+   * @param g  the graphics device.
+   * @param w  the button width.
+   * @param h  the button height.
+   */
+  private void paintNorthBorder(Graphics g, int w, int h) 
+  {
+    if (isEnabled())
+      {
+        g.setColor(MetalLookAndFeel.getControlDarkShadow());
+        g.drawLine(0, 0, 0, h - 1);
+         
+        g.setColor(MetalLookAndFeel.getControlHighlight());
+        g.drawLine(1, 0, 1, h - 1);
+        g.drawLine(1, 0, w - 1, 0);
+      }
+    else
+      {
+        g.setColor(MetalLookAndFeel.getControlDisabled());
+        g.drawLine(0, 0, 0, h - 1);
+      }
+  }
+  
+  /**
+   * Paints the border for a button with a address@hidden #SOUTH} direction 
that
+   * belongs to a scroll bar that is not free standing.
+   * 
+   * @param g  the graphics device.
+   * @param w  the button width.
+   * @param h  the button height.
+   */
+  private void paintSouthBorder(Graphics g, int w, int h)
+  {
+    if (isEnabled())
+      {
+        g.setColor(MetalLookAndFeel.getControlDarkShadow());
+        g.drawLine(0, 0, 0, h - 1);
+        g.drawLine(0, h - 1, w - 1, h - 1);
+         
+        g.setColor(MetalLookAndFeel.getControlHighlight());
+        g.drawLine(1, 0, 1, h - 1);
+        g.drawLine(1, 0, w - 1, 0);
+        
+        g.setColor(MetalLookAndFeel.getControl());
+        g.drawLine(1, h - 1, 1, h - 1);
+      }
+    else
+      {
+        g.setColor(MetalLookAndFeel.getControlDisabled());
+        g.drawLine(0, 0, 0, h - 1);
+      }
+  }
+
+  /**
+   * Paints the border for a button with an address@hidden #EAST} direction 
that
+   * belongs to a scroll bar that is not free standing.
+   * 
+   * @param g  the graphics device.
+   * @param w  the button width.
+   * @param h  the button height.
+   */
+  private void paintEastBorder(Graphics g, int w, int h)
+  {
+    if (isEnabled())
+      {
+        g.setColor(MetalLookAndFeel.getControlDarkShadow());
+        g.drawLine(0, 0, w - 1, 0);
+        g.drawLine(w - 1, 2, w - 1, h - 1);
+        g.setColor(MetalLookAndFeel.getControlHighlight());
+        g.drawLine(0, 1, w - 2, 1);
+        g.drawLine(0, 1, 0, h - 1);
+      }
+    else
+      {
+        g.setColor(MetalLookAndFeel.getControlDisabled());
+        g.drawLine(0, 0, w - 1, 0);
+      }
+  }
+  
+  /**
+   * Paints the border for a button with a address@hidden #WEST} direction that
+   * belongs to a scroll bar that is not free standing.
+   * 
+   * @param g  the graphics device.
+   * @param w  the button width.
+   * @param h  the button height.
+   */
+  private void paintWestBorder(Graphics g, int w, int h)
+  {
+    Rectangle bounds = SwingUtilities.getLocalBounds(this);
+    if (isEnabled())
+      {
+        g.setColor(MetalLookAndFeel.getControlDarkShadow());
+        g.drawLine(0, 0, bounds.width - 1, 0);
+        g.setColor(MetalLookAndFeel.getControlHighlight());
+        g.drawLine(0, 1, bounds.width - 1, 1);
+        g.drawLine(0, 1, 0, bounds.height - 1);
+      }
+    else
+      {
+        g.setColor(MetalLookAndFeel.getControlDisabled());
+        g.drawLine(0, 0, bounds.width - 1, 0);
+      }
+  }
+    
+  /**
+   * Returns the preferred size for the button, which varies depending on 
+   * the direction of the button and whether or not it is free standing.
+   * 
+   * @return The preferred size.
+   */
+  public Dimension getPreferredSize()
+  {
+    int adj = 1;
+    if (!freeStanding)
+      adj = 2;
+    
+    if (direction == EAST)
+      return new Dimension(buttonWidth - adj, buttonWidth);    
+    else if (direction == WEST)
+      return new Dimension(buttonWidth - 2, buttonWidth);
+    else if (direction == SOUTH)
+      return new Dimension(buttonWidth, buttonWidth - adj);
+    else // assume NORTH
+      return new Dimension(buttonWidth, buttonWidth - 2);
+  }
+  
+  /**
+   * Returns the minimum size for the button.
+   * 
+   * @return The minimum size for the button.
+   */
+  public Dimension getMinimumSize()
+  {
+    return getPreferredSize();
+  }
+ 
+  /**
+   * Returns the maximum size for the button.
+   * 
+   * @return <code>Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE)</code>.
+   */
+  public Dimension getMaximumSize()
+  {
+    if (maximumSize == null)
+      maximumSize = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
+    return maximumSize; 
+  }
+  
+}
Index: javax/swing/plaf/metal/MetalUtils.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/metal/MetalUtils.java,v
retrieving revision 1.2
diff -u -r1.2 MetalUtils.java
--- javax/swing/plaf/metal/MetalUtils.java      2 Jul 2005 20:32:51 -0000       
1.2
+++ javax/swing/plaf/metal/MetalUtils.java      8 Sep 2005 08:52:13 -0000
@@ -1,4 +1,4 @@
-/* Metaltils.java
+/* MetalUtils.java
 Copyright (C) 2005 Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
@@ -57,7 +57,7 @@
    * @param y the Y coordinate of the upper left corner of the rectangle to
    *     fill
    * @param w the width of the rectangle to fill
-   * @param w the height of the rectangle to fill
+   * @param h the height of the rectangle to fill
    * @param light the light color to use
    * @param dark the dark color to use
    */
@@ -68,7 +68,7 @@
     for (int mY = y; mY < (y + h); mY++)
       {
         // set color alternating with every line
-        if ((mY % 2) == 0)
+        if (((mY - y) % 2) == 0)
           g.setColor(light);
         else
           g.setColor(dark);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]