001: /* ====================================================================
002: * The QueryForm License, Version 1.1
003: *
004: * Copyright (c) 1998 - 2003 David F. Glasser. All rights
005: * reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution,
020: * if any, must include the following acknowledgment:
021: * "This product includes software developed by
022: * David F. Glasser."
023: * Alternately, this acknowledgment may appear in the software itself,
024: * if and wherever such third-party acknowledgments normally appear.
025: *
026: * 4. The names "QueryForm" and "David F. Glasser" must
027: * not be used to endorse or promote products derived from this
028: * software without prior written permission. For written
029: * permission, please contact dglasser@pobox.com.
030: *
031: * 5. Products derived from this software may not be called "QueryForm",
032: * nor may "QueryForm" appear in their name, without prior written
033: * permission of David F. Glasser.
034: *
035: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL DAVID F. GLASSER, THE APACHE SOFTWARE
039: * FOUNDATION OR ITS CONTRIBUTORS, OR ANY AUTHORS OR DISTRIBUTORS
040: * OF THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: * ====================================================================
049: *
050: * This product includes software developed by the
051: * Apache Software Foundation (http://www.apache.org/).
052: *
053: * ====================================================================
054: *
055: * $Source: /cvsroot/qform/qform/src/org/glasser/swing/BevelArrowIcon.java,v $
056: * $Revision: 1.2 $
057: * $Author: dglasser $
058: * $Date: 2003/07/05 02:54:33 $
059: *
060: * --------------------------------------------------------------------
061: */
062: package org.glasser.swing;
063:
064: import javax.swing.*;
065: import java.awt.*;
066:
067: /**
068: * This is a very limited, basic Icon implementation that can be used as a beveled
069: * arrow pointing up or down on a JButton.
070: */
071: public class BevelArrowIcon implements Icon, java.io.Serializable {
072:
073: /**
074: * Given the base of an equilateral triangle, this multiplier will give you its height.
075: */
076: protected final static double heightMultiplier = 0.86602540378443864676372317075294;
077:
078: protected double size = 16.0;
079:
080: public final static int UP = 0;
081:
082: public final static int DOWN = 1;
083:
084: protected int direction = UP;
085:
086: protected int margin;
087:
088: protected int height;
089:
090: protected int width;
091:
092: protected int middle;
093:
094: /**
095: * Constructs a BevelArrowIcon with a base of 10 pixels, and the given direction.
096: *
097: * @param direction indicates what direction the arrow should point, either BevelArrowIcon.UP
098: * or BevelArrowIcon.DOWN.
099: */
100: public BevelArrowIcon(int direction) {
101: this (10.0, direction);
102: }
103:
104: /**
105: * Constructs a BevelArrowIcon with a base of "size" pixels, and the given direction.
106: *
107: * @param direction indicates what direction the arrow should point, either BevelArrowIcon.UP
108: * or BevelArrowIcon.DOWN.
109: */
110: public BevelArrowIcon(double size, int direction) {
111: if (size < 8 || size > Integer.MAX_VALUE) {
112: throw new IllegalArgumentException(
113: "BevelArrowIcon(int size): size must be between 8 and "
114: + Integer.MAX_VALUE + ".");
115: }
116:
117: this .size = size;
118:
119: width = (int) size;
120:
121: height = (int) (heightMultiplier * size);
122:
123: margin = (int) ((size - (heightMultiplier * size)) / 2.0);
124:
125: middle = (int) (size / 2.0);
126:
127: if (direction == UP) {
128: this .direction = UP;
129: } else {
130: this .direction = DOWN;
131: }
132: }
133:
134: /**
135: * Draw the icon at the specified location. Icon implementations
136: * may use the Component argument to get properties useful for
137: * painting, e.g. the foreground or background color.
138: */
139: public void paintIcon(Component c, Graphics g, int x, int y) {
140:
141: Color background = c.getBackground();
142: Color highlight = background.brighter();
143: Color shadowColor = background.darker();
144: if (c instanceof AbstractButton) {
145: ButtonModel model = ((AbstractButton) c).getModel();
146:
147: // if the parent component is a button that is "armed" (pressed
148: // but not yet released) then paint the background in the
149: // dark shadow color.
150: if (model.isArmed()) {
151: shadowColor = shadowColor.darker();
152: }
153: }
154:
155: int topY = y + margin;
156: int bottomY = topY + height;
157: int rightX = x + width;
158: int axisX = x + middle;
159:
160: if (direction == UP) {
161:
162: g.setColor(highlight);
163: g.drawLine(x, bottomY, rightX, bottomY);
164: g.drawLine(rightX, bottomY, axisX, topY);
165:
166: g.setColor(shadowColor);
167: g.drawLine(axisX, topY, x, bottomY);
168:
169: } else {
170: g.setColor(shadowColor);
171: g.drawLine(x, topY, rightX, topY);
172: g.drawLine(x, topY, axisX, bottomY);
173:
174: g.setColor(highlight);
175: g.drawLine(axisX, bottomY, rightX, topY);
176:
177: }
178: }
179:
180: /**
181: * Returns the icon's width.
182: *
183: * @return an int specifying the fixed width of the icon.
184: */
185: public int getIconWidth() {
186: return width;
187: }
188:
189: /**
190: * Returns the icon's height.
191: *
192: * @return an int specifying the fixed height of the icon.
193: */
194: public int getIconHeight() {
195: return width;
196: }
197:
198: /**
199: * Launches a small demonstration program.
200: */
201: public static void main(String[] args) throws Exception {
202:
203: JFrame frame = new JFrame();
204: JButton button = new JButton("Click");
205: frame.setSize(200, 200);
206: frame.setContentPane(new JPanel());
207: frame.getContentPane().add(button);
208:
209: button.addActionListener(new java.awt.event.ActionListener() {
210: int counter = 0;
211: BevelArrowIcon upIcon = new BevelArrowIcon(UP);
212: BevelArrowIcon downIcon = new BevelArrowIcon(DOWN);
213:
214: public void actionPerformed(java.awt.event.ActionEvent e) {
215: JButton button = (JButton) e.getSource();
216: counter++;
217: if (counter % 2 == 0) {
218: button.setIcon(upIcon);
219: } else {
220: button.setIcon(downIcon);
221: }
222:
223: }
224: });
225:
226: frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
227: frame.setVisible(true);
228:
229: }
230:
231: }
|