classpath-patches
[Top][All Lists]
Advanced

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

[cp-patches] FYI: BasicArrowButton


From: David Gilbert
Subject: [cp-patches] FYI: BasicArrowButton
Date: Thu, 20 Oct 2005 15:56:17 +0100
User-agent: Mozilla Thunderbird 1.0.6 (X11/20050728)

This patch cleans up the BasicArrowButton class, reworking the paintTriangle() method in particular to be a closer match to the reference implementation:

2005-10-20  David Gilbert  <address@hidden>

        * javax/swing/plaf/basic/BasicArrowButton.java: Updated API docs all
        over, plus:
        (defaultSize): removed field,
        (upIcon): removed field,
        (downIcon): removed field,
        (leftIcon): removed field,
        (rightIcon): removed field,
        (darkShadow): changed color value,
        (paint): ignore insets for triangle positioning, but check 'armed'
        state,
        (paintTriangle): delegate to new private methods depending on
        direction,
        (paintTriangleNorth): new private method,
        (paintTriangleSouth): new private method,
        (paintTriangleEast): new private method,
        (paintTriangleWest): new private method.

Sorry for mixing the API doc updates in there as well, but I haven't got time to make a separate patch right now...

Regards,

Dave
Index: javax/swing/plaf/basic/BasicArrowButton.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/swing/plaf/basic/BasicArrowButton.java,v
retrieving revision 1.15
diff -u -r1.15 BasicArrowButton.java
--- javax/swing/plaf/basic/BasicArrowButton.java        19 Oct 2005 14:54:55 
-0000      1.15
+++ javax/swing/plaf/basic/BasicArrowButton.java        20 Oct 2005 14:35:50 
-0000
@@ -39,43 +39,30 @@
 package javax.swing.plaf.basic;
 
 import java.awt.Color;
-import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Graphics;
-import java.awt.Insets;
 import java.awt.Polygon;
 import java.awt.Rectangle;
 
-import javax.swing.AbstractButton;
+import javax.swing.ButtonModel;
 import javax.swing.JButton;
 import javax.swing.SwingConstants;
-import javax.swing.border.Border;
 
 /**
- * This class draws simple arrow buttons for the Basic Look and Feel.
+ * A button that displays an arrow (triangle) that points address@hidden 
#NORTH},
+ * address@hidden #SOUTH}, address@hidden #EAST} or address@hidden #WEST}.  
This button is used by
+ * the address@hidden BasicComboBoxUI} class.
+ * 
+ * @see BasicComboBoxUI#createArrowButton
  */
 public class BasicArrowButton extends JButton implements SwingConstants
 {
-  /** The default size of the Arrow buttons. */
-  private static int defaultSize = 12;
 
-  /** The Polygon that points up. */
-  private static Polygon upIcon = new Polygon(new int[] { 0, 5, 9 },
-                                              new int[] { 7, 2, 7 }, 3);
-
-  /** The Polygon that points down. */
-  private static Polygon downIcon = new Polygon(new int[] { 1, 5, 9 },
-                                                new int[] { 3, 7, 3 }, 3);
-
-  /** The Polygon that points left. */
-  private static Polygon leftIcon = new Polygon(new int[] { 7, 3, 7 },
-                                                new int[] { 1, 5, 9 }, 3);
-
-  /** The Polygon that points right. */
-  private static Polygon rightIcon = new Polygon(new int[] { 3, 7, 3 },
-                                                 new int[] { 1, 5, 9 }, 3);
-
-  /** The direction to point in. */
+  /** 
+   * The direction that the arrow points. 
+   * 
+   * @see #getDirection()
+   */
   protected int direction;
 
   /**
@@ -90,7 +77,7 @@
    * edges of the button.
    * This is package-private to avoid an accessor method.
    */
-  transient Color darkShadow = Color.DARK_GRAY;
+  transient Color darkShadow = new Color(102, 102, 102);
 
   /**
    * The top and left edges of the button.
@@ -99,9 +86,10 @@
   transient Color highlight = Color.WHITE;
 
   /**
-   * Creates a new BasicArrowButton object.
+   * Creates a new <code>BasicArrowButton</code> object.
    *
-   * @param direction The direction the arrow points in.
+   * @param direction The direction the arrow points in (one of: 
+   * address@hidden #NORTH}, address@hidden #SOUTH}, address@hidden #EAST} and 
address@hidden #WEST}).
    */
   public BasicArrowButton(int direction)
   {
@@ -113,7 +101,8 @@
    * Creates a new BasicArrowButton object with the given colors and
    * direction.
    *
-   * @param direction The direction to point in.
+   * @param direction The direction to point in (one of: 
+   * address@hidden #NORTH}, address@hidden #SOUTH}, address@hidden #EAST} and 
address@hidden #WEST}).
    * @param background The background color.
    * @param shadow The shadow color.
    * @param darkShadow The dark shadow color.
@@ -130,9 +119,10 @@
   }
 
   /**
-   * This method returns whether the focus can traverse to this component.
+   * Returns whether the focus can traverse to this component.  This method
+   * always returns <code>false</code>.
    *
-   * @return Whether the focus can traverse to this component.
+   * @return <code>false</code>.
    */
   public boolean isFocusTraversable()
   {
@@ -140,7 +130,8 @@
   }
 
   /**
-   * This method returns the direction of the arrow.
+   * Returns the direction of the arrow (one of: address@hidden #NORTH}, 
+   * address@hidden #SOUTH}, address@hidden #EAST} and address@hidden #WEST}).
    *
    * @return The direction of the arrow.
    */
@@ -150,9 +141,10 @@
   }
 
   /**
-   * This method changes the direction of the arrow.
+   * Sets the direction of the arrow.
    *
-   * @param dir The new direction of the arrow.
+   * @param dir The new direction of the arrow (one of: address@hidden 
#NORTH}, 
+   *            address@hidden #SOUTH}, address@hidden #EAST} and 
address@hidden #WEST}).
    */
   public void setDirection(int dir)
   {
@@ -160,7 +152,7 @@
   }
 
   /**
-   * This method paints the arrow button. The painting is delegated to the
+   * Paints the arrow button. The painting is delegated to the
    * paintTriangle method.
    *
    * @param g The Graphics object to paint with.
@@ -168,13 +160,17 @@
   public void paint(Graphics g)
   {
     super.paint(g);
-    Insets insets = getInsets();
     Rectangle bounds = getBounds();
-    int x = insets.left
-            + (bounds.width - insets.left - insets.right - defaultSize) / 2;
-    int y = insets.top
-            + (bounds.height - insets.left - insets.right - defaultSize) / 2;
-    paintTriangle(g, x, y, defaultSize, direction, isEnabled());
+    int size = bounds.height / 4;
+    int x = (bounds.width - size) / 2;
+    int y = (bounds.height - size) / 2;
+    ButtonModel m = getModel();
+    if (m.isArmed())
+      {
+        x++;
+        y++;
+      }
+    paintTriangle(g, x, y, size, direction, isEnabled());
   }
 
   /** The preferred size for the button. */
@@ -188,9 +184,9 @@
     = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
   
   /**
-   * This method returns the preferred size of the arrow button.
+   * Returns the preferred size of the arrow button.
    *
-   * @return The preferred size.
+   * @return The preferred size (always 16 x 16).
    */
   public Dimension getPreferredSize()
   {
@@ -198,9 +194,9 @@
   }
 
   /**
-   * This method returns the minimum size of the arrow button.
+   * Returns the minimum size of the arrow button.
    *
-   * @return The minimum size.
+   * @return The minimum size (always 5 x 5).
    */
   public Dimension getMinimumSize()
   {
@@ -208,7 +204,7 @@
   }
 
   /**
-   * This method returns the maximum size of the arrow button.
+   * Returns the maximum size of the arrow button.
    *
    * @return The maximum size.
    */
@@ -218,103 +214,203 @@
   }
 
   /**
-   * The method paints a triangle with the given size and direction at the
-   * given x and y coordinates.
+   * Paints a triangle with the given size, location and direction.  It is 
+   * difficult to explain the rationale behind the positioning of the triangle
+   * relative to the given (x, y) position - by trial and error we seem to 
+   * match the behaviour of the reference implementation (which is missing a 
+   * specification for this method).
    *
-   * @param g The Graphics object to paint with.
-   * @param x The x coordinate to paint at.
-   * @param y The y coordinate to paint at.
-   * @param size The size of the icon.
-   * @param direction The direction of the icon.
-   * @param isEnabled Whether it is enabled.
+   * @param g  the graphics device.
+   * @param x  the x-coordinate for the triangle's location.
+   * @param y  the y-coordinate for the triangle's location.
+   * @param size  the arrow size (depth).
+   * @param direction  the direction of the arrow (one of: address@hidden 
#NORTH}, 
+   *            address@hidden #SOUTH}, address@hidden #EAST} and 
address@hidden #WEST}).
+   * @param isEnabled  if <code>true</code> the arrow is drawn in the enabled
+   *                   state, otherwise it is drawn in the disabled state.
    */
   public void paintTriangle(Graphics g, int x, int y, int size, int direction,
                             boolean isEnabled)
   {
-    Polygon arrow = null;
-    switch (direction)
-      {
-      case NORTH:
-       arrow = upIcon;
-       break;
-      case SOUTH:
-       arrow = downIcon;
-       break;
-      case EAST:
-      case RIGHT:
-       arrow = rightIcon;
-       break;
-      case WEST:
-      case LEFT:
-       arrow = leftIcon;
-       break;
-      }
-
-    int[] xPoints = arrow.xpoints;
-    int[] yPoints = arrow.ypoints;
-    int x1;
-    int y1;
-    int x2;
-    int y2;
-    x1 = y1 = x2 = y2 = 0;
-
-    if (size != defaultSize)
-      {
-       float scale = size * 1f / defaultSize;
-       for (int i = 0; i < 3; i++)
-         {
-           xPoints[i] *= scale;
-           yPoints[i] *= scale;
-         }
-      }
-    g.translate(x, y);
-
+    Color savedColor = g.getColor();
     switch (direction)
       {
       case NORTH:
-       x1 = xPoints[0] + 2;
-       y1 = yPoints[0];
-       y2 = y1;
-       x2 = xPoints[2] - 1;
-       break;
+        paintTriangleNorth(g, x, y, size, isEnabled);
+        break;
       case SOUTH:
-       x1 = xPoints[1];
-       y1 = yPoints[1];
-       x2 = xPoints[2];
-       y2 = yPoints[2];
-       break;
+        paintTriangleSouth(g, x, y, size, isEnabled);
+        break;
       case LEFT:
       case WEST:
-       x1 = xPoints[0] + 1;
-       y1 = yPoints[0] + 1;
-       x2 = x1;
-       y2 = yPoints[2] + 1;
-       break;
+        paintTriangleWest(g, x, y, size, isEnabled);
+        break;
       case RIGHT:
       case EAST:
-       x1 = xPoints[2];
-       y1 = yPoints[2] + 1;
-       x2 = xPoints[1] - 1;
-       y2 = yPoints[1] + 1;
-       break;
+        paintTriangleEast(g, x, y, size, isEnabled);
+        break;
       }
-    Color saved = g.getColor();
-
+    g.setColor(savedColor);
+  }
+  
+  /**
+   * Paints an upward-pointing triangle.  This method is called by the 
+   * address@hidden #paintTriangle(Graphics, int, int, int, int, boolean)} 
method.
+   * 
+   * @param g  the graphics device.
+   * @param x  the x-coordinate for the anchor point.
+   * @param y  the y-coordinate for the anchor point.
+   * @param size  the arrow size (depth).
+   * @param isEnabled  if <code>true</code> the arrow is drawn in the enabled
+   *                   state, otherwise it is drawn in the disabled state.
+   */
+  private void paintTriangleNorth(Graphics g, int x, int y, int size, 
+          boolean isEnabled)
+  {
+    int tipX = x + (size - 2) / 2;
+    int tipY = y;
+    int baseX1 = tipX - (size - 1);
+    int baseX2 = tipX + (size - 1);
+    int baseY = y + (size - 1);
+    Polygon triangle = new Polygon();
+    triangle.addPoint(tipX, tipY);
+    triangle.addPoint(baseX1, baseY);
+    triangle.addPoint(baseX2, baseY);
     if (isEnabled)
-      {
-       g.setColor(Color.DARK_GRAY);
-
-       if (arrow != null)
-         g.fillPolygon(xPoints, yPoints, 3);
-      }
+     {
+       g.setColor(Color.DARK_GRAY);
+       g.fillPolygon(triangle);
+       g.drawPolygon(triangle);
+     }
     else
-      {
-       g.setColor(Color.GRAY);
-       g.fillPolygon(xPoints, yPoints, 3);
-       g.setColor(Color.WHITE);
-       g.drawLine(x1, y1, x2, y2);
-      }
-    g.setColor(saved);
-    g.translate(-x, -y);
+     {
+       g.setColor(Color.GRAY);
+       g.fillPolygon(triangle);
+       g.drawPolygon(triangle);
+       g.setColor(Color.WHITE);
+       g.drawLine(baseX1 + 1, baseY + 1, baseX2 + 1, baseY + 1);
+     }
+  }
+  
+  /**
+   * Paints an downward-pointing triangle.  This method is called by the 
+   * address@hidden #paintTriangle(Graphics, int, int, int, int, boolean)} 
method.
+   * 
+   * @param g  the graphics device.
+   * @param x  the x-coordinate for the anchor point.
+   * @param y  the y-coordinate for the anchor point.
+   * @param size  the arrow size (depth).
+   * @param isEnabled  if <code>true</code> the arrow is drawn in the enabled
+   *                   state, otherwise it is drawn in the disabled state.
+   */
+  private void paintTriangleSouth(Graphics g, int x, int y, int size, 
+          boolean isEnabled)
+  {
+    int tipX = x + (size - 2) / 2;
+    int tipY = y + (size - 1);
+    int baseX1 = tipX - (size - 1);
+    int baseX2 = tipX + (size - 1);
+    int baseY = y;
+    Polygon triangle = new Polygon();
+    triangle.addPoint(tipX, tipY);
+    triangle.addPoint(baseX1, baseY);
+    triangle.addPoint(baseX2, baseY);
+    if (isEnabled)
+     {
+       g.setColor(Color.DARK_GRAY);
+       g.fillPolygon(triangle);
+       g.drawPolygon(triangle);
+     }
+    else
+     {
+       g.setColor(Color.GRAY);
+       g.fillPolygon(triangle);
+       g.drawPolygon(triangle);
+       g.setColor(Color.WHITE);
+       g.drawLine(tipX + 1, tipY, baseX2, baseY + 1);
+       g.drawLine(tipX + 1, tipY + 1, baseX2 + 1, baseY + 1);
+     }
+  }
+  
+  /**
+   * Paints a right-pointing triangle.  This method is called by the 
+   * address@hidden #paintTriangle(Graphics, int, int, int, int, boolean)} 
method.
+   * 
+   * @param g  the graphics device.
+   * @param x  the x-coordinate for the anchor point.
+   * @param y  the y-coordinate for the anchor point.
+   * @param size  the arrow size (depth).
+   * @param isEnabled  if <code>true</code> the arrow is drawn in the enabled
+   *                   state, otherwise it is drawn in the disabled state.
+   */
+  private void paintTriangleEast(Graphics g, int x, int y, int size, 
+          boolean isEnabled)
+  {
+    int tipX = x + (size - 1);
+    int tipY = y + (size - 2) / 2;
+    int baseX = x;
+    int baseY1 = tipY - (size - 1);
+    int baseY2 = tipY + (size - 1);
+    
+    Polygon triangle = new Polygon();
+    triangle.addPoint(tipX, tipY);
+    triangle.addPoint(baseX, baseY1);
+    triangle.addPoint(baseX, baseY2);
+    if (isEnabled)
+     {
+       g.setColor(Color.DARK_GRAY);
+       g.fillPolygon(triangle);
+       g.drawPolygon(triangle);
+     }
+    else
+     {
+       g.setColor(Color.GRAY);
+       g.fillPolygon(triangle);
+       g.drawPolygon(triangle);
+       g.setColor(Color.WHITE);
+       g.drawLine(baseX + 1, baseY2, tipX, tipY + 1);
+       g.drawLine(baseX + 1, baseY2 + 1, tipX + 1, tipY + 1);
+     }
   }
+  
+  /**
+   * Paints a left-pointing triangle.  This method is called by the 
+   * address@hidden #paintTriangle(Graphics, int, int, int, int, boolean)} 
method.
+   * 
+   * @param g  the graphics device.
+   * @param x  the x-coordinate for the anchor point.
+   * @param y  the y-coordinate for the anchor point.
+   * @param size  the arrow size (depth).
+   * @param isEnabled  if <code>true</code> the arrow is drawn in the enabled
+   *                   state, otherwise it is drawn in the disabled state.
+   */
+  private void paintTriangleWest(Graphics g, int x, int y, int size, 
+          boolean isEnabled)
+  {
+    int tipX = x;
+    int tipY = y + (size - 2) / 2;
+    int baseX = x + (size - 1);
+    int baseY1 = tipY - (size - 1);
+    int baseY2 = tipY + (size - 1);
+    
+    Polygon triangle = new Polygon();
+    triangle.addPoint(tipX, tipY);
+    triangle.addPoint(baseX, baseY1);
+    triangle.addPoint(baseX, baseY2);
+    if (isEnabled)
+     {
+       g.setColor(Color.DARK_GRAY);
+       g.fillPolygon(triangle);
+       g.drawPolygon(triangle);
+     }
+    else
+     {
+       g.setColor(Color.GRAY);
+       g.fillPolygon(triangle);
+       g.drawPolygon(triangle);
+       g.setColor(Color.WHITE);
+       g.drawLine(baseX + 1, baseY1 + 1, baseX + 1, baseY2 + 1);
+     }
+  }
+  
 }

reply via email to

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