1 /* BasicArrowButton.java --
2 Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
39 package javax
.swing
.plaf
.basic
;
41 import java
.awt
.Color
;
42 import java
.awt
.Dimension
;
43 import java
.awt
.Graphics
;
44 import java
.awt
.Polygon
;
46 import javax
.swing
.ButtonModel
;
47 import javax
.swing
.JButton
;
48 import javax
.swing
.SwingConstants
;
51 * A button that displays an arrow (triangle) that points {@link #NORTH},
52 * {@link #SOUTH}, {@link #EAST} or {@link #WEST}. This button is used by
53 * the {@link BasicComboBoxUI} class.
55 * @see BasicComboBoxUI#createArrowButton
57 public class BasicArrowButton
extends JButton
implements SwingConstants
61 * The direction that the arrow points.
63 * @see #getDirection()
65 protected int direction
;
68 * The color the arrow is painted in if disabled and the bottom and right
69 * edges of the button.
70 * This is package-private to avoid an accessor method.
72 transient Color shadow
= Color
.GRAY
;
75 * The color the arrow is painted in if enabled and the bottom and right
76 * edges of the button.
77 * This is package-private to avoid an accessor method.
79 transient Color darkShadow
= new Color(102, 102, 102);
82 * The top and left edges of the button.
83 * This is package-private to avoid an accessor method.
85 transient Color highlight
= Color
.WHITE
;
88 * Creates a new <code>BasicArrowButton</code> object with an arrow pointing
89 * in the specified direction. If the <code>direction</code> is not one of
90 * the specified constants, no arrow is drawn.
92 * @param direction The direction the arrow points in (one of:
93 * {@link #NORTH}, {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
95 public BasicArrowButton(int direction
)
98 setDirection(direction
);
103 * Creates a new BasicArrowButton object with the given colors and
106 * @param direction The direction to point in (one of:
107 * {@link #NORTH}, {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
108 * @param background The background color.
109 * @param shadow The shadow color.
110 * @param darkShadow The dark shadow color.
111 * @param highlight The highlight color.
113 public BasicArrowButton(int direction
, Color background
, Color shadow
,
114 Color darkShadow
, Color highlight
)
117 setBackground(background
);
118 this.shadow
= shadow
;
119 this.darkShadow
= darkShadow
;
120 this.highlight
= highlight
;
125 * Returns whether the focus can traverse to this component. This method
126 * always returns <code>false</code>.
128 * @return <code>false</code>.
130 public boolean isFocusTraversable()
136 * Returns the direction of the arrow (one of: {@link #NORTH},
137 * {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
139 * @return The direction of the arrow.
141 public int getDirection()
147 * Sets the direction of the arrow.
149 * @param dir The new direction of the arrow (one of: {@link #NORTH},
150 * {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
152 public void setDirection(int dir
)
154 this.direction
= dir
;
158 * Paints the arrow button. The painting is delegated to the
159 * paintTriangle method.
161 * @param g The Graphics object to paint with.
163 public void paint(Graphics g
)
167 int height
= getHeight();
168 int size
= height
/ 4;
170 int x
= (getWidth() - size
) / 2;
171 int y
= (height
- size
) / 2;
173 ButtonModel m
= getModel();
180 paintTriangle(g
, x
, y
, size
, direction
, isEnabled());
184 * Returns the preferred size of the arrow button.
186 * @return The preferred size (always 16 x 16).
188 public Dimension
getPreferredSize()
190 // since Dimension is NOT immutable, we must return a new instance
191 // every time (if we return a cached value, the caller might modify it)
192 // - tests show that the reference implementation does the same.
193 return new Dimension(16, 16);
197 * Returns the minimum size of the arrow button.
199 * @return The minimum size (always 5 x 5).
201 public Dimension
getMinimumSize()
203 // since Dimension is NOT immutable, we must return a new instance
204 // every time (if we return a cached value, the caller might modify it)
205 // - tests show that the reference implementation does the same.
206 return new Dimension(5, 5);
210 * Returns the maximum size of the arrow button.
212 * @return The maximum size (always Integer.MAX_VALUE x Integer.MAX_VALUE).
214 public Dimension
getMaximumSize()
216 // since Dimension is NOT immutable, we must return a new instance
217 // every time (if we return a cached value, the caller might modify it)
218 // - tests show that the reference implementation does the same.
219 return new Dimension(Integer
.MAX_VALUE
, Integer
.MAX_VALUE
);
223 * Paints a triangle with the given size, location and direction. It is
224 * difficult to explain the rationale behind the positioning of the triangle
225 * relative to the given (x, y) position - by trial and error we seem to
226 * match the behaviour of the reference implementation (which is missing a
227 * specification for this method).
229 * @param g the graphics device.
230 * @param x the x-coordinate for the triangle's location.
231 * @param y the y-coordinate for the triangle's location.
232 * @param size the arrow size (depth).
233 * @param direction the direction of the arrow (one of: {@link #NORTH},
234 * {@link #SOUTH}, {@link #EAST} and {@link #WEST}).
235 * @param isEnabled if <code>true</code> the arrow is drawn in the enabled
236 * state, otherwise it is drawn in the disabled state.
238 public void paintTriangle(Graphics g
, int x
, int y
, int size
, int direction
,
241 Color savedColor
= g
.getColor();
245 paintTriangleNorth(g
, x
, y
, size
, isEnabled
);
248 paintTriangleSouth(g
, x
, y
, size
, isEnabled
);
252 paintTriangleWest(g
, x
, y
, size
, isEnabled
);
256 paintTriangleEast(g
, x
, y
, size
, isEnabled
);
259 g
.setColor(savedColor
);
263 * Paints an upward-pointing triangle. This method is called by the
264 * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method.
266 * @param g the graphics device.
267 * @param x the x-coordinate for the anchor point.
268 * @param y the y-coordinate for the anchor point.
269 * @param size the arrow size (depth).
270 * @param isEnabled if <code>true</code> the arrow is drawn in the enabled
271 * state, otherwise it is drawn in the disabled state.
273 private void paintTriangleNorth(Graphics g
, int x
, int y
, int size
,
276 int tipX
= x
+ (size
- 2) / 2;
278 int baseX1
= tipX
- (size
- 1);
279 int baseX2
= tipX
+ (size
- 1);
280 int baseY
= y
+ (size
- 1);
281 Polygon triangle
= new Polygon();
282 triangle
.addPoint(tipX
, tipY
);
283 triangle
.addPoint(baseX1
, baseY
);
284 triangle
.addPoint(baseX2
, baseY
);
287 g
.setColor(Color
.DARK_GRAY
);
288 g
.fillPolygon(triangle
);
289 g
.drawPolygon(triangle
);
293 g
.setColor(Color
.GRAY
);
294 g
.fillPolygon(triangle
);
295 g
.drawPolygon(triangle
);
296 g
.setColor(Color
.WHITE
);
297 g
.drawLine(baseX1
+ 1, baseY
+ 1, baseX2
+ 1, baseY
+ 1);
302 * Paints an downward-pointing triangle. This method is called by the
303 * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method.
305 * @param g the graphics device.
306 * @param x the x-coordinate for the anchor point.
307 * @param y the y-coordinate for the anchor point.
308 * @param size the arrow size (depth).
309 * @param isEnabled if <code>true</code> the arrow is drawn in the enabled
310 * state, otherwise it is drawn in the disabled state.
312 private void paintTriangleSouth(Graphics g
, int x
, int y
, int size
,
315 int tipX
= x
+ (size
- 2) / 2;
316 int tipY
= y
+ (size
- 1);
317 int baseX1
= tipX
- (size
- 1);
318 int baseX2
= tipX
+ (size
- 1);
320 Polygon triangle
= new Polygon();
321 triangle
.addPoint(tipX
, tipY
);
322 triangle
.addPoint(baseX1
, baseY
);
323 triangle
.addPoint(baseX2
, baseY
);
326 g
.setColor(Color
.DARK_GRAY
);
327 g
.fillPolygon(triangle
);
328 g
.drawPolygon(triangle
);
332 g
.setColor(Color
.GRAY
);
333 g
.fillPolygon(triangle
);
334 g
.drawPolygon(triangle
);
335 g
.setColor(Color
.WHITE
);
336 g
.drawLine(tipX
+ 1, tipY
, baseX2
, baseY
+ 1);
337 g
.drawLine(tipX
+ 1, tipY
+ 1, baseX2
+ 1, baseY
+ 1);
342 * Paints a right-pointing triangle. This method is called by the
343 * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method.
345 * @param g the graphics device.
346 * @param x the x-coordinate for the anchor point.
347 * @param y the y-coordinate for the anchor point.
348 * @param size the arrow size (depth).
349 * @param isEnabled if <code>true</code> the arrow is drawn in the enabled
350 * state, otherwise it is drawn in the disabled state.
352 private void paintTriangleEast(Graphics g
, int x
, int y
, int size
,
355 int tipX
= x
+ (size
- 1);
356 int tipY
= y
+ (size
- 2) / 2;
358 int baseY1
= tipY
- (size
- 1);
359 int baseY2
= tipY
+ (size
- 1);
361 Polygon triangle
= new Polygon();
362 triangle
.addPoint(tipX
, tipY
);
363 triangle
.addPoint(baseX
, baseY1
);
364 triangle
.addPoint(baseX
, baseY2
);
367 g
.setColor(Color
.DARK_GRAY
);
368 g
.fillPolygon(triangle
);
369 g
.drawPolygon(triangle
);
373 g
.setColor(Color
.GRAY
);
374 g
.fillPolygon(triangle
);
375 g
.drawPolygon(triangle
);
376 g
.setColor(Color
.WHITE
);
377 g
.drawLine(baseX
+ 1, baseY2
, tipX
, tipY
+ 1);
378 g
.drawLine(baseX
+ 1, baseY2
+ 1, tipX
+ 1, tipY
+ 1);
383 * Paints a left-pointing triangle. This method is called by the
384 * {@link #paintTriangle(Graphics, int, int, int, int, boolean)} method.
386 * @param g the graphics device.
387 * @param x the x-coordinate for the anchor point.
388 * @param y the y-coordinate for the anchor point.
389 * @param size the arrow size (depth).
390 * @param isEnabled if <code>true</code> the arrow is drawn in the enabled
391 * state, otherwise it is drawn in the disabled state.
393 private void paintTriangleWest(Graphics g
, int x
, int y
, int size
,
397 int tipY
= y
+ (size
- 2) / 2;
398 int baseX
= x
+ (size
- 1);
399 int baseY1
= tipY
- (size
- 1);
400 int baseY2
= tipY
+ (size
- 1);
402 Polygon triangle
= new Polygon();
403 triangle
.addPoint(tipX
, tipY
);
404 triangle
.addPoint(baseX
, baseY1
);
405 triangle
.addPoint(baseX
, baseY2
);
408 g
.setColor(Color
.DARK_GRAY
);
409 g
.fillPolygon(triangle
);
410 g
.drawPolygon(triangle
);
414 g
.setColor(Color
.GRAY
);
415 g
.fillPolygon(triangle
);
416 g
.drawPolygon(triangle
);
417 g
.setColor(Color
.WHITE
);
418 g
.drawLine(baseX
+ 1, baseY1
+ 1, baseX
+ 1, baseY2
+ 1);