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