001: /*
002: * Copyright (c) 2001-2007 JGoodies Karsten Lentzsch. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JGoodies Karsten Lentzsch nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package com.jgoodies.looks.plastic;
032:
033: import java.awt.Color;
034: import java.awt.Component;
035: import java.awt.Graphics;
036: import java.io.Serializable;
037:
038: import javax.swing.ButtonModel;
039: import javax.swing.Icon;
040: import javax.swing.JCheckBox;
041: import javax.swing.JComponent;
042: import javax.swing.JMenuItem;
043: import javax.swing.plaf.UIResource;
044: import javax.swing.plaf.metal.MetalLookAndFeel;
045:
046: /**
047: * Factory class that vends <code>Icon</code>s for the
048: * JGoodies Plastic look and feel.
049: * These icons are used extensively in Plastic via the defaults mechanism.
050: * While other look and feels often use GIFs for icons, creating icons
051: * in code facilitates switching to other themes.
052: * <p>
053: * Each method in this class returns either an <code>Icon</code> or <code>null</code>,
054: * where <code>null</code> implies that there is no default icon.
055: *
056: * @author Karsten Lentzsch
057: * @version $Revision: 1.5 $
058: */
059:
060: final class PlasticIconFactory {
061:
062: private PlasticIconFactory() {
063: // Overrides default constructor; prevents instantiation.
064: }
065:
066: // Helper method utilized by the CheckBoxIcon and the CheckBoxMenuItemIcon.
067: private static void drawCheck(Graphics g, int x, int y) {
068: g.translate(x, y);
069: g.drawLine(3, 5, 3, 5);
070: g.fillRect(3, 6, 2, 2);
071: g.drawLine(4, 8, 9, 3);
072: g.drawLine(5, 8, 9, 4);
073: g.drawLine(5, 9, 9, 5);
074: g.translate(-x, -y);
075: }
076:
077: private static class CheckBoxIcon implements Icon, UIResource,
078: Serializable {
079:
080: private static final int SIZE = 13;
081:
082: public int getIconWidth() {
083: return SIZE;
084: }
085:
086: public int getIconHeight() {
087: return SIZE;
088: }
089:
090: public void paintIcon(Component c, Graphics g, int x, int y) {
091: JCheckBox cb = (JCheckBox) c;
092: ButtonModel model = cb.getModel();
093:
094: if (model.isEnabled()) {
095: if (cb.isBorderPaintedFlat()) {
096: g.setColor(PlasticLookAndFeel
097: .getControlDarkShadow());
098: g.drawRect(x, y, SIZE - 2, SIZE - 2);
099: // inside box
100: g
101: .setColor(PlasticLookAndFeel
102: .getControlHighlight());
103: g.fillRect(x + 1, y + 1, SIZE - 3, SIZE - 3);
104: } else if (model.isPressed() && model.isArmed()) {
105: g.setColor(MetalLookAndFeel.getControlShadow());
106: g.fillRect(x, y, SIZE - 1, SIZE - 1);
107: PlasticUtils.drawPressed3DBorder(g, x, y, SIZE,
108: SIZE);
109: } else {
110: PlasticUtils.drawFlush3DBorder(g, x, y, SIZE, SIZE);
111: }
112: g.setColor(MetalLookAndFeel.getControlInfo());
113: } else {
114: g.setColor(MetalLookAndFeel.getControlShadow());
115: g.drawRect(x, y, SIZE - 2, SIZE - 2);
116: }
117:
118: if (model.isSelected()) {
119: drawCheck(g, x, y);
120: }
121: }
122:
123: }
124:
125: private static class CheckBoxMenuItemIcon implements Icon,
126: UIResource, Serializable {
127:
128: private static final int SIZE = 13;
129:
130: public int getIconWidth() {
131: return SIZE;
132: }
133:
134: public int getIconHeight() {
135: return SIZE;
136: }
137:
138: public void paintIcon(Component c, Graphics g, int x, int y) {
139: JMenuItem b = (JMenuItem) c;
140: if (b.isSelected()) {
141: drawCheck(g, x, y + 1);
142: }
143: }
144: }
145:
146: private static class RadioButtonMenuItemIcon implements Icon,
147: UIResource, Serializable {
148:
149: private static final int SIZE = 13;
150:
151: public int getIconWidth() {
152: return SIZE;
153: }
154:
155: public int getIconHeight() {
156: return SIZE;
157: }
158:
159: public void paintIcon(Component c, Graphics g, int x, int y) {
160: JMenuItem b = (JMenuItem) c;
161: if (b.isSelected()) {
162: drawDot(g, x, y);
163: }
164: }
165:
166: private void drawDot(Graphics g, int x, int y) {
167: g.translate(x, y);
168: g.drawLine(5, 4, 8, 4);
169: g.fillRect(4, 5, 6, 4);
170: g.drawLine(5, 9, 8, 9);
171: g.translate(-x, -y);
172: }
173: }
174:
175: private static class MenuArrowIcon implements Icon, UIResource,
176: Serializable {
177:
178: private static final int WIDTH = 4;
179: private static final int HEIGHT = 8;
180:
181: public void paintIcon(Component c, Graphics g, int x, int y) {
182: JMenuItem b = (JMenuItem) c;
183:
184: g.translate(x, y);
185: if (PlasticUtils.isLeftToRight(b)) {
186: g.drawLine(0, 0, 0, 7);
187: g.drawLine(1, 1, 1, 6);
188: g.drawLine(2, 2, 2, 5);
189: g.drawLine(3, 3, 3, 4);
190: } else {
191: g.drawLine(4, 0, 4, 7);
192: g.drawLine(3, 1, 3, 6);
193: g.drawLine(2, 2, 2, 5);
194: g.drawLine(1, 3, 1, 4);
195: }
196: g.translate(-x, -y);
197: }
198:
199: public int getIconWidth() {
200: return WIDTH;
201: }
202:
203: public int getIconHeight() {
204: return HEIGHT;
205: }
206:
207: }
208:
209: /**
210: * Paints a minus sign button icon used in trees.
211: * Uses a white background, gray border, and black foreground.
212: */
213: private static class ExpandedTreeIcon implements Icon, Serializable {
214:
215: protected static final int SIZE = 9;
216: protected static final int HALF_SIZE = 4;
217:
218: public void paintIcon(Component c, Graphics g, int x, int y) {
219: g.setColor(Color.WHITE);
220: g.fillRect(x, y, SIZE - 1, SIZE - 1);
221: g.setColor(Color.GRAY);
222: g.drawRect(x, y, SIZE - 1, SIZE - 1);
223: g.setColor(Color.BLACK);
224: g.drawLine(x + 2, y + HALF_SIZE, x + (SIZE - 3), y
225: + HALF_SIZE);
226: }
227:
228: public int getIconWidth() {
229: return SIZE;
230: }
231:
232: public int getIconHeight() {
233: return SIZE;
234: }
235: }
236:
237: /**
238: * The plus sign button icon used in trees.
239: */
240: private static class CollapsedTreeIcon extends ExpandedTreeIcon {
241: public void paintIcon(Component c, Graphics g, int x, int y) {
242: super .paintIcon(c, g, x, y);
243: g.drawLine(x + HALF_SIZE, y + 2, x + HALF_SIZE, y
244: + (SIZE - 3));
245: }
246: }
247:
248: /**
249: * The arrow button used in comboboxes.
250: */
251: private static class ComboBoxButtonIcon implements Icon,
252: Serializable {
253:
254: public void paintIcon(Component c, Graphics g, int x, int y) {
255: JComponent component = (JComponent) c;
256: int iconWidth = getIconWidth();
257:
258: g.translate(x, y);
259:
260: g.setColor(component.isEnabled() ? MetalLookAndFeel
261: .getControlInfo() : MetalLookAndFeel
262: .getControlShadow());
263: g.drawLine(0, 0, iconWidth - 1, 0);
264: g.drawLine(1, 1, 1 + (iconWidth - 3), 1);
265: g.drawLine(2, 2, 2 + (iconWidth - 5), 2);
266: g.drawLine(3, 3, 3 + (iconWidth - 7), 3);
267:
268: /*
269: int startY = (((h + 1) - arrowHeight) / 2) + arrowHeight - 1;
270: int startX = (w / 2);
271:
272: // System.out.println( "startX2 :" + startX + " startY2 :"+startY);
273:
274: for (int line = 0; line < arrowHeight; line++) {
275: g.drawLine(
276: startX - line,
277: startY - line,
278: startX + line + 1,
279: startY - line);
280: }*/
281: g.translate(-x, -y);
282: }
283:
284: public int getIconWidth() {
285: return 8;
286: }
287:
288: public int getIconHeight() {
289: return 4;
290: }
291: }
292:
293: // Cached Access to Icons ***********************************************************
294:
295: private static Icon checkBoxIcon;
296: private static Icon checkBoxMenuItemIcon;
297: private static Icon radioButtonMenuItemIcon;
298: private static Icon menuArrowIcon;
299: private static Icon expandedTreeIcon;
300: private static Icon collapsedTreeIcon;
301: private static Icon comboBoxButtonIcon;
302:
303: /**
304: * Answers an <code>Icon</code> used for <code>JCheckBox</code>es.
305: */
306: static Icon getCheckBoxIcon() {
307: if (checkBoxIcon == null) {
308: checkBoxIcon = new CheckBoxIcon();
309: }
310: return checkBoxIcon;
311: }
312:
313: /**
314: * Answers an <code>Icon</code> used for <code>JCheckButtonMenuItem</code>s.
315: */
316: static Icon getCheckBoxMenuItemIcon() {
317: if (checkBoxMenuItemIcon == null) {
318: checkBoxMenuItemIcon = new CheckBoxMenuItemIcon();
319: }
320: return checkBoxMenuItemIcon;
321: }
322:
323: /**
324: * Answers an <code>Icon</code> used for <code>JRadioButtonMenuItem</code>s.
325: */
326: static Icon getRadioButtonMenuItemIcon() {
327: if (radioButtonMenuItemIcon == null) {
328: radioButtonMenuItemIcon = new RadioButtonMenuItemIcon();
329: }
330: return radioButtonMenuItemIcon;
331: }
332:
333: /**
334: * Answers an <code>Icon</code> used for arrows in <code>JMenu</code>s.
335: */
336: static Icon getMenuArrowIcon() {
337: if (menuArrowIcon == null) {
338: menuArrowIcon = new MenuArrowIcon();
339: }
340: return menuArrowIcon;
341: }
342:
343: /**
344: * Answers an <code>Icon</code> used in <code>JTree</code>s.
345: */
346: static Icon getExpandedTreeIcon() {
347: if (expandedTreeIcon == null) {
348: expandedTreeIcon = new ExpandedTreeIcon();
349: }
350: return expandedTreeIcon;
351: }
352:
353: /**
354: * Answers an <code>Icon</code> used in <code>JTree</code>s.
355: */
356: static Icon getCollapsedTreeIcon() {
357: if (collapsedTreeIcon == null) {
358: collapsedTreeIcon = new CollapsedTreeIcon();
359: }
360: return collapsedTreeIcon;
361: }
362:
363: /**
364: * Answers an <code>Icon</code> used in <code>JComboBox</code>es.
365: */
366: static Icon getComboBoxButtonIcon() {
367: if (comboBoxButtonIcon == null) {
368: comboBoxButtonIcon = new ComboBoxButtonIcon();
369: }
370: return comboBoxButtonIcon;
371: }
372:
373: }
|