001 /*
002 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025 package javax.swing.plaf.basic;
026
027 import java.awt.Dimension;
028 import java.awt.Graphics;
029 import java.awt.Color;
030
031 import javax.swing.*;
032 import javax.swing.plaf.UIResource;
033
034 /**
035 * JButton object that draws a scaled Arrow in one of the cardinal directions.
036 * <p>
037 * <strong>Warning:</strong>
038 * Serialized objects of this class will not be compatible with
039 * future Swing releases. The current serialization support is
040 * appropriate for short term storage or RMI between applications running
041 * the same version of Swing. As of 1.4, support for long term storage
042 * of all JavaBeans<sup><font size="-2">TM</font></sup>
043 * has been added to the <code>java.beans</code> package.
044 * Please see {@link java.beans.XMLEncoder}.
045 *
046 * @version 1.35 05/05/07
047 * @author David Kloba
048 */
049 public class BasicArrowButton extends JButton implements SwingConstants {
050 /**
051 * The direction of the arrow. One of
052 * {@code SwingConstants.NORTH}, {@code SwingConstants.SOUTH},
053 * {@code SwingConstants.EAST} or {@code SwingConstants.WEST}.
054 */
055 protected int direction;
056
057 private Color shadow;
058 private Color darkShadow;
059 private Color highlight;
060
061 /**
062 * Creates a {@code BasicArrowButton} whose arrow
063 * is drawn in the specified direction and with the specified
064 * colors.
065 *
066 * @param direction the direction of the arrow; one of
067 * {@code SwingConstants.NORTH}, {@code SwingConstants.SOUTH},
068 * {@code SwingConstants.EAST} or {@code SwingConstants.WEST}
069 * @param background the background color of the button
070 * @param shadow the color of the shadow
071 * @param darkShadow the color of the dark shadow
072 * @param highlight the color of the highlight
073 * @since 1.4
074 */
075 public BasicArrowButton(int direction, Color background,
076 Color shadow, Color darkShadow, Color highlight) {
077 super ();
078 setRequestFocusEnabled(false);
079 setDirection(direction);
080 setBackground(background);
081 this .shadow = shadow;
082 this .darkShadow = darkShadow;
083 this .highlight = highlight;
084 }
085
086 /**
087 * Creates a {@code BasicArrowButton} whose arrow
088 * is drawn in the specified direction.
089 *
090 * @param direction the direction of the arrow; one of
091 * {@code SwingConstants.NORTH}, {@code SwingConstants.SOUTH},
092 * {@code SwingConstants.EAST} or {@code SwingConstants.WEST}
093 */
094 public BasicArrowButton(int direction) {
095 this (direction, UIManager.getColor("control"), UIManager
096 .getColor("controlShadow"), UIManager
097 .getColor("controlDkShadow"), UIManager
098 .getColor("controlLtHighlight"));
099 }
100
101 /**
102 * Returns the direction of the arrow.
103 *
104 * @param direction the direction of the arrow; one of
105 * {@code SwingConstants.NORTH},
106 * {@code SwingConstants.SOUTH}, {@code SwingConstants.EAST}
107 * or {@code SwingConstants.WEST}
108 */
109 public int getDirection() {
110 return direction;
111 }
112
113 /**
114 * Sets the direction of the arrow.
115 *
116 * @param direction the direction of the arrow; one of
117 * of {@code SwingConstants.NORTH},
118 * {@code SwingConstants.SOUTH},
119 * {@code SwingConstants.EAST} or {@code SwingConstants.WEST}
120 */
121 public void setDirection(int dir) {
122 direction = dir;
123 }
124
125 public void paint(Graphics g) {
126 Color origColor;
127 boolean isPressed, isEnabled;
128 int w, h, size;
129
130 w = getSize().width;
131 h = getSize().height;
132 origColor = g.getColor();
133 isPressed = getModel().isPressed();
134 isEnabled = isEnabled();
135
136 g.setColor(getBackground());
137 g.fillRect(1, 1, w - 2, h - 2);
138
139 /// Draw the proper Border
140 if (getBorder() != null && !(getBorder() instanceof UIResource)) {
141 paintBorder(g);
142 } else if (isPressed) {
143 g.setColor(shadow);
144 g.drawRect(0, 0, w - 1, h - 1);
145 } else {
146 // Using the background color set above
147 g.drawLine(0, 0, 0, h - 1);
148 g.drawLine(1, 0, w - 2, 0);
149
150 g.setColor(highlight); // inner 3D border
151 g.drawLine(1, 1, 1, h - 3);
152 g.drawLine(2, 1, w - 3, 1);
153
154 g.setColor(shadow); // inner 3D border
155 g.drawLine(1, h - 2, w - 2, h - 2);
156 g.drawLine(w - 2, 1, w - 2, h - 3);
157
158 g.setColor(darkShadow); // black drop shadow __|
159 g.drawLine(0, h - 1, w - 1, h - 1);
160 g.drawLine(w - 1, h - 1, w - 1, 0);
161 }
162
163 // If there's no room to draw arrow, bail
164 if (h < 5 || w < 5) {
165 g.setColor(origColor);
166 return;
167 }
168
169 if (isPressed) {
170 g.translate(1, 1);
171 }
172
173 // Draw the arrow
174 size = Math.min((h - 4) / 3, (w - 4) / 3);
175 size = Math.max(size, 2);
176 paintTriangle(g, (w - size) / 2, (h - size) / 2, size,
177 direction, isEnabled);
178
179 // Reset the Graphics back to it's original settings
180 if (isPressed) {
181 g.translate(-1, -1);
182 }
183 g.setColor(origColor);
184
185 }
186
187 /**
188 * Returns the preferred size of the {@code BasicArrowButton}.
189 *
190 * @return the preferred size
191 */
192 public Dimension getPreferredSize() {
193 return new Dimension(16, 16);
194 }
195
196 /**
197 * Returns the minimum size of the {@code BasicArrowButton}.
198 *
199 * @return the minimum size
200 */
201 public Dimension getMinimumSize() {
202 return new Dimension(5, 5);
203 }
204
205 /**
206 * Returns the maximum size of the {@code BasicArrowButton}.
207 *
208 * @return the maximum size
209 */
210 public Dimension getMaximumSize() {
211 return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
212 }
213
214 /**
215 * Returns whether the arrow button should get the focus.
216 * {@code BasicArrowButton}s are used as a child component of
217 * composite components such as {@code JScrollBar} and
218 * {@code JComboBox}. Since the composite component typically gets the
219 * focus, this method is overriden to return {@code false}.
220 *
221 * @return {@code false}
222 */
223 public boolean isFocusTraversable() {
224 return false;
225 }
226
227 /**
228 * Paints a triangle.
229 *
230 * @param g the {@code Graphics} to draw to
231 * @param x the x coordinate
232 * @param y the y coordinate
233 * @param size the size of the triangle to draw
234 * @param direction the direction in which to draw the arrow;
235 * one of {@code SwingConstants.NORTH},
236 * {@code SwingConstants.SOUTH}, {@code SwingConstants.EAST} or
237 * {@code SwingConstants.WEST}
238 * @param isEnabled whether or not the arrow is drawn enabled
239 */
240 public void paintTriangle(Graphics g, int x, int y, int size,
241 int direction, boolean isEnabled) {
242 Color oldColor = g.getColor();
243 int mid, i, j;
244
245 j = 0;
246 size = Math.max(size, 2);
247 mid = (size / 2) - 1;
248
249 g.translate(x, y);
250 if (isEnabled)
251 g.setColor(darkShadow);
252 else
253 g.setColor(shadow);
254
255 switch (direction) {
256 case NORTH:
257 for (i = 0; i < size; i++) {
258 g.drawLine(mid - i, i, mid + i, i);
259 }
260 if (!isEnabled) {
261 g.setColor(highlight);
262 g.drawLine(mid - i + 2, i, mid + i, i);
263 }
264 break;
265 case SOUTH:
266 if (!isEnabled) {
267 g.translate(1, 1);
268 g.setColor(highlight);
269 for (i = size - 1; i >= 0; i--) {
270 g.drawLine(mid - i, j, mid + i, j);
271 j++;
272 }
273 g.translate(-1, -1);
274 g.setColor(shadow);
275 }
276
277 j = 0;
278 for (i = size - 1; i >= 0; i--) {
279 g.drawLine(mid - i, j, mid + i, j);
280 j++;
281 }
282 break;
283 case WEST:
284 for (i = 0; i < size; i++) {
285 g.drawLine(i, mid - i, i, mid + i);
286 }
287 if (!isEnabled) {
288 g.setColor(highlight);
289 g.drawLine(i, mid - i + 2, i, mid + i);
290 }
291 break;
292 case EAST:
293 if (!isEnabled) {
294 g.translate(1, 1);
295 g.setColor(highlight);
296 for (i = size - 1; i >= 0; i--) {
297 g.drawLine(j, mid - i, j, mid + i);
298 j++;
299 }
300 g.translate(-1, -1);
301 g.setColor(shadow);
302 }
303
304 j = 0;
305 for (i = size - 1; i >= 0; i--) {
306 g.drawLine(j, mid - i, j, mid + i);
307 j++;
308 }
309 break;
310 }
311 g.translate(-x, -y);
312 g.setColor(oldColor);
313 }
314
315 }
|