GNU Classpath (0.20) | |
Frames | No Frames |
1: /* BasicArrowButton.java -- 2: Copyright (C) 2004, 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing.plaf.basic; 40: 41: import java.awt.Color; 42: import java.awt.Dimension; 43: import java.awt.Graphics; 44: import java.awt.Polygon; 45: import java.awt.Rectangle; 46: 47: import javax.swing.ButtonModel; 48: import javax.swing.JButton; 49: import javax.swing.SwingConstants; 50: 51: /** 52: * A button that displays an arrow (triangle) that points {@link #NORTH}, 53: * {@link #SOUTH}, {@link #EAST} or {@link #WEST}. This button is used by 54: * the {@link BasicComboBoxUI} class. 55: * 56: * @see BasicComboBoxUI#createArrowButton 57: */ 58: public class BasicArrowButton extends JButton implements SwingConstants 59: { 60: 61: /** 62: * The direction that the arrow points. 63: * 64: * @see #getDirection() 65: */ 66: protected int direction; 67: 68: /** 69: * The color the arrow is painted in if disabled and the bottom and right 70: * edges of the button. 71: * This is package-private to avoid an accessor method. 72: */ 73: transient Color shadow = Color.GRAY; 74: 75: /** 76: * The color the arrow is painted in if enabled and the bottom and right 77: * edges of the button. 78: * This is package-private to avoid an accessor method. 79: */ 80: transient Color darkShadow = new Color(102, 102, 102); 81: 82: /** 83: * The top and left edges of the button. 84: * This is package-private to avoid an accessor method. 85: */ 86: transient Color highlight = Color.WHITE; 87: 88: /** 89: * Creates a new <code>BasicArrowButton</code> object. 90: * 91: * @param direction The direction the arrow points in (one of: 92: * {@link #NORTH}, {@link #SOUTH}, {@link #EAST} and {@link #WEST}). 93: */ 94: public BasicArrowButton(int direction) 95: { 96: super(); 97: setDirection(direction); 98: } 99: 100: /** 101: * Creates a new BasicArrowButton object with the given colors and 102: * direction. 103: * 104: * @param direction The direction to point in (one of: 105: * {@link #NORTH}, {@link #SOUTH}, {@link #EAST} and {@link #WEST}). 106: * @param background The background color. 107: * @param shadow The shadow color. 108: * @param darkShadow The dark shadow color. 109: * @param highlight The highlight color. 110: */ 111: public BasicArrowButton(int direction, Color background, Color shadow, 112: Color darkShadow, Color highlight) 113: { 114: this(direction); 115: setBackground(background); 116: this.shadow = shadow; 117: this.darkShadow = darkShadow; 118: this.highlight = highlight; 119: } 120: 121: /** 122: * Returns whether the focus can traverse to this component. This method 123: * always returns <code>false</code>. 124: * 125: * @return <code>false</code>. 126: */ 127: public boolean isFocusTraversable() 128: { 129: return false; 130: } 131: 132: /** 133: * Returns the direction of the arrow (one of: {@link #NORTH}, 134: * {@link #SOUTH}, {@link #EAST} and {@link #WEST}). 135: * 136: * @return The direction of the arrow. 137: */ 138: public int getDirection() 139: { 140: return direction; 141: } 142: 143: /** 144: * Sets the direction of the arrow. 145: * 146: * @param dir The new direction of the arrow (one of: {@link #NORTH}, 147: * {@link #SOUTH}, {@link #EAST} and {@link #WEST}). 148: */ 149: public void setDirection(int dir) 150: { 151: this.direction = dir; 152: } 153: 154: /** 155: * Paints the arrow button. The painting is delegated to the 156: * paintTriangle method. 157: * 158: * @param g The Graphics object to paint with. 159: */ 160: public void paint(Graphics g) 161: { 162: super.paint(g); 163: Rectangle bounds = getBounds(); 164: int size = bounds.height / 4; 165: int x = bounds.x + (bounds.width - size) / 2; 166: int y = (bounds.height - size) / 4; 167: ButtonModel m = getModel(); 168: if (m.isArmed()) 169: { 170: x++; 171: y++; 172: } 173: paintTriangle(g, x, y, size, direction, isEnabled()); 174: } 175: 176: /** The preferred size for the button. */ 177: private static final Dimension PREFERRED_SIZE = new Dimension(16, 16); 178: 179: /** The minimum size for the button. */ 180: private static final Dimension MINIMUM_SIZE = new Dimension(5, 5); 181: 182: /** The maximum size for the button. */ 183: private static final Dimension MAXIMUM_SIZE 184: = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); 185: 186: /** 187: * Returns the preferred size of the arrow button. 188: * 189: * @return The preferred size (always 16 x 16). 190: */ 191: public Dimension getPreferredSize() 192: { 193: return PREFERRED_SIZE; 194: } 195: 196: /** 197: * Returns the minimum size of the arrow button. 198: * 199: * @return The minimum size (always 5 x 5). 200: */ 201: public Dimension getMinimumSize() 202: { 203: return MINIMUM_SIZE; 204: } 205: 206: /** 207: * Returns the maximum size of the arrow button. 208: * 209: * @return The maximum size. 210: */ 211: public Dimension getMaximumSize() 212: { 213: return MAXIMUM_SIZE; 214: } 215: 216: /** 217: * Paints a triangle with the given size, location and direction. It is 218: * difficult to explain the rationale behind the positioning of the triangle 219: * relative to the given (x, y) position - by trial and error we seem to 220: * match the behaviour of the reference implementation (which is missing a 221: * specification for this method). 222: * 223: * @param g the graphics device. 224: * @param x the x-coordinate for the triangle's location. 225: * @param y the y-coordinate for the triangle's location. 226: * @param size the arrow size (depth). 227: * @param direction the direction of the arrow (one of: {@link #NORTH}, 228: * {@link #SOUTH}, {@link #EAST} and {@link #WEST}). 229: * @param isEnabled if <code>true</code> the arrow is drawn in the enabled 230: * state, otherwise it is drawn in the disabled state. 231: */ 232: public void paintTriangle(Graphics g, int x, int y, int size, int direction, 233: boolean isEnabled) 234: { 235: Color savedColor = g.getColor(); 236: switch (direction) 237: { 238: case NORTH: 239: paintTriangleNorth(g, x, y, size, isEnabled); 240: break; 241: case SOUTH: 242: paintTriangleSouth(g, x, y, size, isEnabled); 243: break; 244: case LEFT: 245: case WEST: 246: paintTriangleWest(g, x, y, size, isEnabled); 247: break; 248: case RIGHT: 249: case EAST: 250: paintTriangleEast(g, x, y, size, isEnabled); 251: break; 252: } 253: g.setColor(savedColor); 254: } 255: 256: /** 257: * Paints an upward-pointing triangle. This method is called by the 258: * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method. 259: * 260: * @param g the graphics device. 261: * @param x the x-coordinate for the anchor point. 262: * @param y the y-coordinate for the anchor point. 263: * @param size the arrow size (depth). 264: * @param isEnabled if <code>true</code> the arrow is drawn in the enabled 265: * state, otherwise it is drawn in the disabled state. 266: */ 267: private void paintTriangleNorth(Graphics g, int x, int y, int size, 268: boolean isEnabled) 269: { 270: int tipX = x + (size - 2) / 2; 271: int tipY = y; 272: int baseX1 = tipX - (size - 1); 273: int baseX2 = tipX + (size - 1); 274: int baseY = y + (size - 1); 275: Polygon triangle = new Polygon(); 276: triangle.addPoint(tipX, tipY); 277: triangle.addPoint(baseX1, baseY); 278: triangle.addPoint(baseX2, baseY); 279: if (isEnabled) 280: { 281: g.setColor(Color.DARK_GRAY); 282: g.fillPolygon(triangle); 283: g.drawPolygon(triangle); 284: } 285: else 286: { 287: g.setColor(Color.GRAY); 288: g.fillPolygon(triangle); 289: g.drawPolygon(triangle); 290: g.setColor(Color.WHITE); 291: g.drawLine(baseX1 + 1, baseY + 1, baseX2 + 1, baseY + 1); 292: } 293: } 294: 295: /** 296: * Paints an downward-pointing triangle. This method is called by the 297: * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method. 298: * 299: * @param g the graphics device. 300: * @param x the x-coordinate for the anchor point. 301: * @param y the y-coordinate for the anchor point. 302: * @param size the arrow size (depth). 303: * @param isEnabled if <code>true</code> the arrow is drawn in the enabled 304: * state, otherwise it is drawn in the disabled state. 305: */ 306: private void paintTriangleSouth(Graphics g, int x, int y, int size, 307: boolean isEnabled) 308: { 309: int tipX = x + (size - 2) / 2; 310: int tipY = y + (size - 1); 311: int baseX1 = tipX - (size - 1); 312: int baseX2 = tipX + (size - 1); 313: int baseY = y; 314: Polygon triangle = new Polygon(); 315: triangle.addPoint(tipX, tipY); 316: triangle.addPoint(baseX1, baseY); 317: triangle.addPoint(baseX2, baseY); 318: if (isEnabled) 319: { 320: g.setColor(Color.DARK_GRAY); 321: g.fillPolygon(triangle); 322: g.drawPolygon(triangle); 323: } 324: else 325: { 326: g.setColor(Color.GRAY); 327: g.fillPolygon(triangle); 328: g.drawPolygon(triangle); 329: g.setColor(Color.WHITE); 330: g.drawLine(tipX + 1, tipY, baseX2, baseY + 1); 331: g.drawLine(tipX + 1, tipY + 1, baseX2 + 1, baseY + 1); 332: } 333: } 334: 335: /** 336: * Paints a right-pointing triangle. This method is called by the 337: * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method. 338: * 339: * @param g the graphics device. 340: * @param x the x-coordinate for the anchor point. 341: * @param y the y-coordinate for the anchor point. 342: * @param size the arrow size (depth). 343: * @param isEnabled if <code>true</code> the arrow is drawn in the enabled 344: * state, otherwise it is drawn in the disabled state. 345: */ 346: private void paintTriangleEast(Graphics g, int x, int y, int size, 347: boolean isEnabled) 348: { 349: int tipX = x + (size - 1); 350: int tipY = y + (size - 2) / 2; 351: int baseX = x; 352: int baseY1 = tipY - (size - 1); 353: int baseY2 = tipY + (size - 1); 354: 355: Polygon triangle = new Polygon(); 356: triangle.addPoint(tipX, tipY); 357: triangle.addPoint(baseX, baseY1); 358: triangle.addPoint(baseX, baseY2); 359: if (isEnabled) 360: { 361: g.setColor(Color.DARK_GRAY); 362: g.fillPolygon(triangle); 363: g.drawPolygon(triangle); 364: } 365: else 366: { 367: g.setColor(Color.GRAY); 368: g.fillPolygon(triangle); 369: g.drawPolygon(triangle); 370: g.setColor(Color.WHITE); 371: g.drawLine(baseX + 1, baseY2, tipX, tipY + 1); 372: g.drawLine(baseX + 1, baseY2 + 1, tipX + 1, tipY + 1); 373: } 374: } 375: 376: /** 377: * Paints a left-pointing triangle. This method is called by the 378: * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method. 379: * 380: * @param g the graphics device. 381: * @param x the x-coordinate for the anchor point. 382: * @param y the y-coordinate for the anchor point. 383: * @param size the arrow size (depth). 384: * @param isEnabled if <code>true</code> the arrow is drawn in the enabled 385: * state, otherwise it is drawn in the disabled state. 386: */ 387: private void paintTriangleWest(Graphics g, int x, int y, int size, 388: boolean isEnabled) 389: { 390: int tipX = x; 391: int tipY = y + (size - 2) / 2; 392: int baseX = x + (size - 1); 393: int baseY1 = tipY - (size - 1); 394: int baseY2 = tipY + (size - 1); 395: 396: Polygon triangle = new Polygon(); 397: triangle.addPoint(tipX, tipY); 398: triangle.addPoint(baseX, baseY1); 399: triangle.addPoint(baseX, baseY2); 400: if (isEnabled) 401: { 402: g.setColor(Color.DARK_GRAY); 403: g.fillPolygon(triangle); 404: g.drawPolygon(triangle); 405: } 406: else 407: { 408: g.setColor(Color.GRAY); 409: g.fillPolygon(triangle); 410: g.drawPolygon(triangle); 411: g.setColor(Color.WHITE); 412: g.drawLine(baseX + 1, baseY1 + 1, baseX + 1, baseY2 + 1); 413: } 414: } 415: 416: }
GNU Classpath (0.20) |