1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 as published by
5    * the Free Software Foundation. This program is distributed in the hope
6    * that it will be useful, but WITHOUT ANY WARRANTY; without even the
7    * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *       http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * Copyright: 2005
18   *     The copyright to this program is held by it's authors.
19   *
20   * ID: $Id: CompositeIcon.java 1966 2009-10-30 01:15:14Z dmsmith $
21   */
22  package org.crosswire.common.swing;
23  
24  import java.awt.Component;
25  import java.awt.Graphics;
26  
27  import javax.swing.Icon;
28  import javax.swing.SwingConstants;
29  
30  /**
31   * CompositeIcon is an Icon implementation which draws two icons with a
32   * specified relative position. LEFT, RIGHT, TOP, BOTTOM: specify how icon1 is
33   * drawn relative to icon2 CENTER: icon1 is drawn first, icon2 is drawn over it
34   * and with horizontal and vertical orientations within the alloted space It's
35   * useful with VTextIcon when you want an icon with your text: if icon1 is the
36   * graphic icon and icon2 is the VTextIcon, you get a similar effect to a JLabel
37   * with a graphic icon and text
38   * 
39   * @see gnu.lgpl.License for license details.<br>
40   *      The copyright to this program is held by it's authors.
41   * @author Lee Ann Rucker [LRucker at mac dot com] from
42   *         http://www.macdevcenter.com/pub/a/mac/2002/03/22/vertical_text.html
43   * @author DM Smith [dmsmith555 at yahoo dot com]
44   */
45  public class CompositeIcon implements Icon {
46  
47      /**
48       * Create a CompositeIcon from the specified Icons, using the default
49       * relative position (icon1 above icon2) and orientations (centered
50       * horizontally and vertically).
51       * 
52       * @param icon1
53       *            Icon
54       * @param icon2
55       *            Icon
56       */
57      public CompositeIcon(Icon icon1, Icon icon2) {
58          this(icon1, icon2, SwingConstants.TOP);
59      }
60  
61      /**
62       * Create a CompositeIcon from the specified Icons, using the specified
63       * relative position and default orientations (centered horizontally and
64       * vertically).
65       * 
66       * @param icon1
67       *            Icon
68       * @param icon2
69       *            Icon
70       * @param position
71       *            int
72       */
73      public CompositeIcon(Icon icon1, Icon icon2, int position) {
74          this(icon1, icon2, position, SwingConstants.CENTER, SwingConstants.CENTER);
75      }
76  
77      /**
78       * Create a CompositeIcon from the specified Icons, using the specified
79       * relative position and orientations.
80       * 
81       * @param icon1
82       *            Icon
83       * @param icon2
84       *            Icon
85       * @param position
86       *            int
87       * @param horizontalOrientation
88       *            int
89       * @param verticalOrientation
90       *            int
91       */
92      public CompositeIcon(Icon icon1, Icon icon2, int position, int horizontalOrientation, int verticalOrientation) {
93          this.icon1 = icon1;
94          this.icon2 = icon2;
95          this.position = position;
96          this.horizontalOrientation = horizontalOrientation;
97          this.verticalOrientation = verticalOrientation;
98      }
99  
100     /*
101      * (non-Javadoc)
102      * 
103      * @see javax.swing.Icon#getIconHeight()
104      */
105     public int getIconHeight() {
106         if (position == SwingConstants.TOP || position == SwingConstants.BOTTOM) {
107             return icon1.getIconHeight() + icon2.getIconHeight();
108         }
109 
110         return Math.max(icon1.getIconHeight(), icon2.getIconHeight());
111     }
112 
113     /*
114      * (non-Javadoc)
115      * 
116      * @see javax.swing.Icon#getIconWidth()
117      */
118     public int getIconWidth() {
119         if (position == SwingConstants.LEFT || position == SwingConstants.RIGHT) {
120             return icon1.getIconWidth() + icon2.getIconWidth();
121         }
122 
123         return Math.max(icon1.getIconWidth(), icon2.getIconWidth());
124     }
125 
126     /*
127      * (non-Javadoc)
128      * 
129      * @see javax.swing.Icon#paintIcon(java.awt.Component, java.awt.Graphics,
130      * int, int)
131      */
132     public void paintIcon(Component c, Graphics g, int x, int y) {
133         int width = getIconWidth();
134         int height = getIconHeight();
135         if (position == SwingConstants.LEFT || position == SwingConstants.RIGHT) {
136             Icon leftIcon;
137             Icon rightIcon;
138             if (position == SwingConstants.LEFT) {
139                 leftIcon = icon1;
140                 rightIcon = icon2;
141             } else {
142                 leftIcon = icon2;
143                 rightIcon = icon1;
144             }
145             // "Left" orientation, because we specify the x position
146             paintIcon(c, g, leftIcon, x, y, width, height, SwingConstants.LEFT, verticalOrientation);
147             paintIcon(c, g, rightIcon, x + leftIcon.getIconWidth(), y, width, height, SwingConstants.LEFT, verticalOrientation);
148         } else if (position == SwingConstants.TOP || position == SwingConstants.BOTTOM) {
149             Icon topIcon;
150             Icon bottomIcon;
151             if (position == SwingConstants.TOP) {
152                 topIcon = icon1;
153                 bottomIcon = icon2;
154             } else {
155                 topIcon = icon2;
156                 bottomIcon = icon1;
157             }
158             // "Top" orientation, because we specify the y position
159             paintIcon(c, g, topIcon, x, y, width, height, horizontalOrientation, SwingConstants.TOP);
160             paintIcon(c, g, bottomIcon, x, y + topIcon.getIconHeight(), width, height, horizontalOrientation, SwingConstants.TOP);
161         } else {
162             paintIcon(c, g, icon1, x, y, width, height, horizontalOrientation, verticalOrientation);
163             paintIcon(c, g, icon2, x, y, width, height, horizontalOrientation, verticalOrientation);
164         }
165     }
166 
167     /**
168      * Paints one icon in the specified rectangle with the given orientations.
169      * 
170      * @param c
171      *            Component
172      * @param g
173      *            Graphics
174      * @param icon
175      *            Icon
176      * @param x
177      *            int
178      * @param y
179      *            int
180      * @param width
181      *            int
182      * @param height
183      *            int
184      * @param hOrientation
185      *            int
186      * @param vOrientation
187      *            int
188      */
189     private void paintIcon(Component c, Graphics g, Icon icon, int x, int y, int width, int height, int hOrientation, int vOrientation) {
190 
191         int xIcon;
192         int yIcon;
193         switch (hOrientation) {
194         case SwingConstants.LEFT:
195             xIcon = x;
196             break;
197         case SwingConstants.RIGHT:
198             xIcon = x + width - icon.getIconWidth();
199             break;
200         default:
201             xIcon = x + (width - icon.getIconWidth()) / 2;
202             break;
203         }
204         switch (vOrientation) {
205         case SwingConstants.TOP:
206             yIcon = y;
207             break;
208         case SwingConstants.BOTTOM:
209             yIcon = y + height - icon.getIconHeight();
210             break;
211         default:
212             yIcon = y + (height - icon.getIconHeight()) / 2;
213             break;
214         }
215         icon.paintIcon(c, g, xIcon, yIcon);
216     }
217 
218     private Icon icon1;
219     private Icon icon2;
220     private int position;
221     private int horizontalOrientation;
222     private int verticalOrientation;
223 }
224