001/* ========================================================================
002 * JCommon : a free general purpose class library for the Java(tm) platform
003 * ========================================================================
004 *
005 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006 * 
007 * Project Info:  http://www.jfree.org/jcommon/index.html
008 *
009 * This library is free software; you can redistribute it and/or modify it 
010 * under the terms of the GNU Lesser General Public License as published by 
011 * the Free Software Foundation; either version 2.1 of the License, or 
012 * (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful, but 
015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
017 * License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this library; if not, write to the Free Software
021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
022 * USA.  
023 *
024 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
025 * in the United States and other countries.]
026 * 
027 * -------------------
028 * BevelArrowIcon.java
029 * -------------------
030 * (C) Copyright 2000-2004, by Nobuo Tamemasa and Contributors.
031 *
032 * Original Author:  Nobuo Tamemasa;
033 * Contributor(s):   David Gilbert (for Object Refinery Limited);
034 *
035 * $Id: BevelArrowIcon.java,v 1.4 2005/11/16 15:58:41 taqua Exp $
036 *
037 * Changes (from 26-Oct-2001)
038 * --------------------------
039 * 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
040 * 13-Oct-2002 : Fixed errors reported by Checkstyle (DG);
041 *
042 */
043
044package org.jfree.ui;
045
046import java.awt.Color;
047import java.awt.Component;
048import java.awt.Graphics;
049
050import javax.swing.Icon;
051import javax.swing.UIManager;
052
053/**
054 * An arrow icon that can point up or down (usually used to indicate the sort direction in a table).
055 * <P>
056 * This class (and also SortButtonRenderer) is based on original code by Nobuo Tamemasa (version
057 * 1.0, 26-Feb-1999) posted on www.codeguru.com.
058 *
059 * @author Nobuo Tamemasa
060 */
061public class BevelArrowIcon implements Icon {
062
063    /** Constant indicating that the arrow is pointing up. */
064    public static final int UP = 0;
065
066    /** Constant indicating that the arrow is pointing down. */
067    public static final int DOWN = 1;
068
069    /** The default arrow size. */
070    private static final int DEFAULT_SIZE = 11;
071
072    /** Edge color 1. */
073    private Color edge1;
074
075    /** Edge color 2. */
076    private Color edge2;
077
078    /** The fill color for the arrow icon. */
079    private Color fill;
080
081    /** The size of the icon. */
082    private int size;
083
084    /** The direction that the arrow is pointing (UP or DOWN). */
085    private int direction;
086
087    /**
088     * Standard constructor - builds an icon with the specified attributes.
089     *
090     * @param direction .
091     * @param isRaisedView .
092     * @param isPressedView .
093     */
094    public BevelArrowIcon(final int direction, 
095                          final boolean isRaisedView, 
096                          final boolean isPressedView) {
097        if (isRaisedView) {
098            if (isPressedView) {
099                init(UIManager.getColor("controlLtHighlight"),
100                     UIManager.getColor("controlDkShadow"),
101                     UIManager.getColor("controlShadow"),
102                     DEFAULT_SIZE, direction);
103            }
104            else {
105                init(UIManager.getColor("controlHighlight"),
106                     UIManager.getColor("controlShadow"),
107                     UIManager.getColor("control"),
108                     DEFAULT_SIZE, direction);
109            }
110        }
111        else {
112            if (isPressedView) {
113                init(UIManager.getColor("controlDkShadow"),
114                     UIManager.getColor("controlLtHighlight"),
115                     UIManager.getColor("controlShadow"),
116                     DEFAULT_SIZE, direction);
117            }
118            else {
119                init(UIManager.getColor("controlShadow"),
120                     UIManager.getColor("controlHighlight"),
121                     UIManager.getColor("control"),
122                     DEFAULT_SIZE, direction);
123            }
124        }
125    }
126
127    /**
128     * Standard constructor - builds an icon with the specified attributes.
129     *
130     * @param edge1  the color of edge1.
131     * @param edge2  the color of edge2.
132     * @param fill  the fill color.
133     * @param size  the size of the arrow icon.
134     * @param direction  the direction that the arrow points.
135     */
136    public BevelArrowIcon(final Color edge1, 
137                          final Color edge2, 
138                          final Color fill, 
139                          final int size, 
140                          final int direction) {
141        init(edge1, edge2, fill, size, direction);
142    }
143
144    /**
145     * Paints the icon at the specified position.  Supports the Icon interface.
146     *
147     * @param c .
148     * @param g .
149     * @param x .
150     * @param y .
151     */
152    public void paintIcon(final Component c, 
153                          final Graphics g, 
154                          final int x, 
155                          final int y) {
156        switch (this.direction) {
157            case DOWN: drawDownArrow(g, x, y); break;
158            case   UP: drawUpArrow(g, x, y);   break;
159        }
160    }
161
162    /**
163     * Returns the width of the icon.  Supports the Icon interface.
164     *
165     * @return the icon width.
166     */
167    public int getIconWidth() {
168        return this.size;
169    }
170
171    /**
172     * Returns the height of the icon.  Supports the Icon interface.
173     * @return the icon height.
174     */
175    public int getIconHeight() {
176        return this.size;
177    }
178
179    /**
180     * Initialises the attributes of the arrow icon.
181     *
182     * @param edge1  the color of edge1.
183     * @param edge2  the color of edge2.
184     * @param fill  the fill color.
185     * @param size  the size of the arrow icon.
186     * @param direction  the direction that the arrow points.
187     */
188    private void init(final Color edge1, 
189                      final Color edge2, 
190                      final Color fill, 
191                      final int size, 
192                      final int direction) {
193        this.edge1 = edge1;
194        this.edge2 = edge2;
195        this.fill = fill;
196        this.size = size;
197        this.direction = direction;
198    }
199
200    /**
201     * Draws the arrow pointing down.
202     *
203     * @param g  the graphics device.
204     * @param xo  ??
205     * @param yo  ??
206     */
207    private void drawDownArrow(final Graphics g, final int xo, final int yo) {
208        g.setColor(this.edge1);
209        g.drawLine(xo, yo,   xo + this.size - 1, yo);
210        g.drawLine(xo, yo + 1, xo + this.size - 3, yo + 1);
211        g.setColor(this.edge2);
212        g.drawLine(xo + this.size - 2, yo + 1, xo + this.size - 1, yo + 1);
213        int x = xo + 1;
214        int y = yo + 2;
215        int dx = this.size - 6;
216        while (y + 1 < yo + this.size) {
217            g.setColor(this.edge1);
218            g.drawLine(x, y,   x + 1, y);
219            g.drawLine(x, y + 1, x + 1, y + 1);
220            if (0 < dx) {
221                g.setColor(this.fill);
222                g.drawLine(x + 2, y,   x + 1 + dx, y);
223                g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);
224            }
225            g.setColor(this.edge2);
226            g.drawLine(x + dx + 2, y,   x + dx + 3, y);
227            g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);
228            x += 1;
229            y += 2;
230            dx -= 2;
231        }
232        g.setColor(this.edge1);
233        g.drawLine(
234            xo + (this.size / 2), yo + this.size - 1, xo + (this.size / 2), yo + this.size - 1
235        );
236    }
237
238    /**
239     * Draws the arrow pointing up.
240     *
241     * @param g  the graphics device.
242     * @param xo  ??
243     * @param yo  ??
244     */
245    private void drawUpArrow(final Graphics g, final int xo, final int yo) {
246        g.setColor(this.edge1);
247        int x = xo + (this.size / 2);
248        g.drawLine(x, yo, x, yo);
249        x--;
250        int y = yo + 1;
251        int dx = 0;
252        while (y + 3 < yo + this.size) {
253            g.setColor(this.edge1);
254            g.drawLine(x, y,   x + 1, y);
255            g.drawLine(x, y + 1, x + 1, y + 1);
256            if (0 < dx) {
257                g.setColor(this.fill);
258                g.drawLine(x + 2, y,   x + 1 + dx, y);
259                g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);
260            }
261            g.setColor(this.edge2);
262            g.drawLine(x + dx + 2, y,   x + dx + 3, y);
263            g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);
264            x -= 1;
265            y += 2;
266            dx += 2;
267        }
268        g.setColor(this.edge1);
269        g.drawLine(xo, yo + this.size - 3,   xo + 1, yo + this.size - 3);
270        g.setColor(this.edge2);
271        g.drawLine(xo + 2, yo + this.size - 2, xo + this.size - 1, yo + this.size - 2);
272        g.drawLine(xo, yo + this.size - 1, xo + this.size, yo + this.size - 1);
273    }
274
275}