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.5 2007/11/02 17:50:36 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;
049import javax.swing.Icon;
050import javax.swing.UIManager;
051
052/**
053 * An arrow icon that can point up or down (usually used to indicate the sort direction in a table).
054 * <P>
055 * This class (and also SortButtonRenderer) is based on original code by Nobuo Tamemasa (version
056 * 1.0, 26-Feb-1999) posted on www.codeguru.com.
057 *
058 * @author Nobuo Tamemasa
059 */
060public class BevelArrowIcon implements Icon {
061
062    /** Constant indicating that the arrow is pointing up. */
063    public static final int UP = 0;
064
065    /** Constant indicating that the arrow is pointing down. */
066    public static final int DOWN = 1;
067
068    /** The default arrow size. */
069    private static final int DEFAULT_SIZE = 11;
070
071    /** Edge color 1. */
072    private Color edge1;
073
074    /** Edge color 2. */
075    private Color edge2;
076
077    /** The fill color for the arrow icon. */
078    private Color fill;
079
080    /** The size of the icon. */
081    private int size;
082
083    /** The direction that the arrow is pointing (UP or DOWN). */
084    private int direction;
085
086    /**
087     * Standard constructor - builds an icon with the specified attributes.
088     *
089     * @param direction .
090     * @param isRaisedView .
091     * @param isPressedView .
092     */
093    public BevelArrowIcon(final int direction, 
094                          final boolean isRaisedView, 
095                          final boolean isPressedView) {
096        if (isRaisedView) {
097            if (isPressedView) {
098                init(UIManager.getColor("controlLtHighlight"),
099                     UIManager.getColor("controlDkShadow"),
100                     UIManager.getColor("controlShadow"),
101                     DEFAULT_SIZE, direction);
102            }
103            else {
104                init(UIManager.getColor("controlHighlight"),
105                     UIManager.getColor("controlShadow"),
106                     UIManager.getColor("control"),
107                     DEFAULT_SIZE, direction);
108            }
109        }
110        else {
111            if (isPressedView) {
112                init(UIManager.getColor("controlDkShadow"),
113                     UIManager.getColor("controlLtHighlight"),
114                     UIManager.getColor("controlShadow"),
115                     DEFAULT_SIZE, direction);
116            }
117            else {
118                init(UIManager.getColor("controlShadow"),
119                     UIManager.getColor("controlHighlight"),
120                     UIManager.getColor("control"),
121                     DEFAULT_SIZE, direction);
122            }
123        }
124    }
125
126    /**
127     * Standard constructor - builds an icon with the specified attributes.
128     *
129     * @param edge1  the color of edge1.
130     * @param edge2  the color of edge2.
131     * @param fill  the fill color.
132     * @param size  the size of the arrow icon.
133     * @param direction  the direction that the arrow points.
134     */
135    public BevelArrowIcon(final Color edge1, 
136                          final Color edge2, 
137                          final Color fill, 
138                          final int size, 
139                          final int direction) {
140        init(edge1, edge2, fill, size, direction);
141    }
142
143    /**
144     * Paints the icon at the specified position.  Supports the Icon interface.
145     *
146     * @param c .
147     * @param g .
148     * @param x .
149     * @param y .
150     */
151    public void paintIcon(final Component c, 
152                          final Graphics g, 
153                          final int x, 
154                          final int y) {
155        switch (this.direction) {
156            case DOWN: drawDownArrow(g, x, y); break;
157            case   UP: drawUpArrow(g, x, y);   break;
158        }
159    }
160
161    /**
162     * Returns the width of the icon.  Supports the Icon interface.
163     *
164     * @return the icon width.
165     */
166    public int getIconWidth() {
167        return this.size;
168    }
169
170    /**
171     * Returns the height of the icon.  Supports the Icon interface.
172     * @return the icon height.
173     */
174    public int getIconHeight() {
175        return this.size;
176    }
177
178    /**
179     * Initialises the attributes of the arrow icon.
180     *
181     * @param edge1  the color of edge1.
182     * @param edge2  the color of edge2.
183     * @param fill  the fill color.
184     * @param size  the size of the arrow icon.
185     * @param direction  the direction that the arrow points.
186     */
187    private void init(final Color edge1, 
188                      final Color edge2, 
189                      final Color fill, 
190                      final int size, 
191                      final int direction) {
192        this.edge1 = edge1;
193        this.edge2 = edge2;
194        this.fill = fill;
195        this.size = size;
196        this.direction = direction;
197    }
198
199    /**
200     * Draws the arrow pointing down.
201     *
202     * @param g  the graphics device.
203     * @param xo  ??
204     * @param yo  ??
205     */
206    private void drawDownArrow(final Graphics g, final int xo, final int yo) {
207        g.setColor(this.edge1);
208        g.drawLine(xo, yo,   xo + this.size - 1, yo);
209        g.drawLine(xo, yo + 1, xo + this.size - 3, yo + 1);
210        g.setColor(this.edge2);
211        g.drawLine(xo + this.size - 2, yo + 1, xo + this.size - 1, yo + 1);
212        int x = xo + 1;
213        int y = yo + 2;
214        int dx = this.size - 6;
215        while (y + 1 < yo + this.size) {
216            g.setColor(this.edge1);
217            g.drawLine(x, y,   x + 1, y);
218            g.drawLine(x, y + 1, x + 1, y + 1);
219            if (0 < dx) {
220                g.setColor(this.fill);
221                g.drawLine(x + 2, y,   x + 1 + dx, y);
222                g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);
223            }
224            g.setColor(this.edge2);
225            g.drawLine(x + dx + 2, y,   x + dx + 3, y);
226            g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);
227            x += 1;
228            y += 2;
229            dx -= 2;
230        }
231        g.setColor(this.edge1);
232        g.drawLine(
233            xo + (this.size / 2), yo + this.size - 1, xo + (this.size / 2), yo + this.size - 1
234        );
235    }
236
237    /**
238     * Draws the arrow pointing up.
239     *
240     * @param g  the graphics device.
241     * @param xo  ??
242     * @param yo  ??
243     */
244    private void drawUpArrow(final Graphics g, final int xo, final int yo) {
245        g.setColor(this.edge1);
246        int x = xo + (this.size / 2);
247        g.drawLine(x, yo, x, yo);
248        x--;
249        int y = yo + 1;
250        int dx = 0;
251        while (y + 3 < yo + this.size) {
252            g.setColor(this.edge1);
253            g.drawLine(x, y,   x + 1, y);
254            g.drawLine(x, y + 1, x + 1, y + 1);
255            if (0 < dx) {
256                g.setColor(this.fill);
257                g.drawLine(x + 2, y,   x + 1 + dx, y);
258                g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);
259            }
260            g.setColor(this.edge2);
261            g.drawLine(x + dx + 2, y,   x + dx + 3, y);
262            g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);
263            x -= 1;
264            y += 2;
265            dx += 2;
266        }
267        g.setColor(this.edge1);
268        g.drawLine(xo, yo + this.size - 3,   xo + 1, yo + this.size - 3);
269        g.setColor(this.edge2);
270        g.drawLine(xo + 2, yo + this.size - 2, xo + this.size - 1, yo + this.size - 2);
271        g.drawLine(xo, yo + this.size - 1, xo + this.size, yo + this.size - 1);
272    }
273
274}