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    
044    package org.jfree.ui;
045    
046    import java.awt.Color;
047    import java.awt.Component;
048    import java.awt.Graphics;
049    import javax.swing.Icon;
050    import 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     */
060    public 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    }