001: /*
002: * Copyright (c) 2004 JETA Software, Inc. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without modification,
005: * 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 JETA Software nor the names of its contributors may
015: * be used to endorse or promote products derived from this software without
016: * 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, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
021: * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
022: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
023: * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
024: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
025: * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026: * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029:
030: package com.jeta.forms.components.colors;
031:
032: import java.awt.BorderLayout;
033: import java.awt.Color;
034: import java.awt.Component;
035: import java.awt.Graphics2D;
036: import java.awt.event.ActionEvent;
037: import java.awt.event.ActionListener;
038: import java.awt.image.BufferedImage;
039: import java.util.Collection;
040: import java.util.HashMap;
041: import java.util.Iterator;
042: import java.util.LinkedList;
043:
044: import javax.swing.Icon;
045: import javax.swing.ImageIcon;
046: import javax.swing.JComboBox;
047: import javax.swing.JLabel;
048: import javax.swing.JList;
049: import javax.swing.JSpinner;
050: import javax.swing.ListCellRenderer;
051: import javax.swing.LookAndFeel;
052: import javax.swing.SpinnerNumberModel;
053: import javax.swing.UIManager;
054: import javax.swing.event.ChangeEvent;
055: import javax.swing.event.ChangeListener;
056:
057: import com.jeta.forms.colormgr.ColorManager;
058: import com.jeta.forms.components.panel.FormPanel;
059: import com.jeta.forms.store.properties.ColorProperty;
060: import com.jeta.open.gui.framework.JETAPanel;
061: import com.jeta.open.registry.JETARegistry;
062:
063: /**
064: * This is an internal component used by the designer and is not meant to be
065: * used independently of the designer.
066: *
067: * A component that allows the user to select a color that is either constant or
068: * based on the current look and feel.
069: *
070: * @author Jeff Tassin
071: */
072: public class ColorDefinitionView extends JETAPanel {
073: private FormPanel m_view;
074:
075: /**
076: * The current color property
077: */
078: private ColorProperty m_color_prop = new ColorProperty();
079:
080: private ColorDefinitionController m_controller;
081:
082: private JComboBox m_key_combo;
083:
084: /**
085: * A JETAColorWell object. This class is not defined in the forms runtime.
086: * It is only used internally by the designer.
087: */
088: private Component m_color_well;
089: private JSpinner m_factor_spinner;
090: private JSpinner m_bright_spinner;
091:
092: /**
093: * A cache of ColorCellValue objects
094: */
095: private static LinkedList m_color_cell_values;
096: /**
097: * The current look and feel
098: */
099: private static LookAndFeel m_look_and_feel;
100:
101: /**
102: * ctor
103: */
104: public ColorDefinitionView() {
105: try {
106: m_view = new FormPanel(
107: "com/jeta/forms/components/colors/colorSelection.jfrm");
108: setLayout(new BorderLayout());
109: add(m_view, BorderLayout.CENTER);
110:
111: m_color_well = m_view
112: .getComponentByName(ColorSelectorNames.ID_COLOR_INKWELL);
113: m_key_combo = m_view
114: .getComboBox(ColorSelectorNames.ID_COLOR_NAME_COMBO);
115:
116: m_key_combo.setRenderer(new ColorCellRenderer());
117: m_key_combo.setName(ColorSelectorNames.ID_COLOR_NAME_COMBO);
118: m_key_combo.removeAllItems();
119:
120: Collection cvalues = getColorCellValues();
121: Iterator iter = cvalues.iterator();
122: while (iter.hasNext()) {
123: m_key_combo.addItem(iter.next());
124: }
125:
126: m_factor_spinner = m_view
127: .getSpinner(ColorSelectorNames.ID_BRIGHTNESS_FACTOR);
128: SpinnerNumberModel model = new SpinnerNumberModel(0.7,
129: 0.05, 1.0, 0.05);
130: m_factor_spinner.setModel(model);
131:
132: m_bright_spinner = m_view
133: .getSpinner(ColorSelectorNames.ID_BRIGHTNESS_VALUE);
134: model = new SpinnerNumberModel(0, -10, 10, 1);
135: m_bright_spinner.setModel(model);
136:
137: m_controller = new ColorDefinitionController();
138:
139: } catch (Exception e) {
140: e.printStackTrace();
141: }
142: }
143:
144: /**
145: * @return the color property
146: */
147: public ColorProperty getColorProperty() {
148: try {
149: ColorProperty cprop = new ColorProperty();
150: cprop.setConstantColor(ColorSelectorUtils
151: .getColor(m_color_well));
152: cprop.setColorKey(getSelectedColorKey());
153:
154: Double bfactor = (Double) m_factor_spinner.getValue();
155: cprop.setBrightnessFactor(bfactor.floatValue());
156:
157: Integer b = (Integer) m_bright_spinner.getValue();
158: cprop.setBrightness(b.intValue());
159: return cprop;
160: } catch (Exception e) {
161: e.printStackTrace();
162: return m_color_prop;
163: }
164: }
165:
166: private static Collection getColorCellValues() {
167: LookAndFeel lf = UIManager.getLookAndFeel();
168: if (m_look_and_feel != lf || m_color_cell_values == null) {
169: if (m_color_cell_values == null)
170: m_color_cell_values = new LinkedList();
171: m_color_cell_values.clear();
172:
173: m_look_and_feel = lf;
174:
175: ColorManager cmgr = (ColorManager) JETARegistry
176: .lookup(ColorManager.COMPONENT_ID);
177: Collection cnames = cmgr.getColorKeys();
178: Iterator iter = cnames.iterator();
179: while (iter.hasNext()) {
180: String cname = (String) iter.next();
181: m_color_cell_values.add(new ColorCellValue(cname, cmgr
182: .getColor(cname, null)));
183: }
184: }
185: return m_color_cell_values;
186: }
187:
188: public String getSelectedColorKey() {
189: ColorCellValue ccv = (ColorCellValue) m_key_combo
190: .getSelectedItem();
191: return ccv.getName();
192: }
193:
194: /**
195: * Adds a color to the view that is not in the color manager
196: */
197: public void prependColor(String key, Color c) {
198: if (key == null)
199: return;
200:
201: /** insert after the 'constant' entry */
202: m_key_combo.insertItemAt(new ColorCellValue(key, c), 1);
203: }
204:
205: /**
206: * Sets the color property
207: */
208: public void setColorProperty(ColorProperty cprop) {
209: try {
210: /** silence the controller so we don't get combo box events */
211: m_controller.setSilent(true);
212: m_color_prop.setValue(cprop);
213: String color_name = cprop.getColorKey();
214: setSelectedColor(color_name);
215: ColorSelectorUtils.setColor(m_color_well, cprop.getColor());
216:
217: m_factor_spinner.setValue(new Double(cprop
218: .getBrightnessFactor()));
219: m_bright_spinner
220: .setValue(new Integer(cprop.getBrightness()));
221: } catch (Exception e) {
222: e.printStackTrace();
223: } finally {
224: m_controller.setSilent(false);
225: }
226: }
227:
228: public void setSelectedColor(String cname) {
229: javax.swing.ComboBoxModel cmodel = m_key_combo.getModel();
230: for (int index = 0; index < cmodel.getSize(); index++) {
231: if (cmodel.getElementAt(index).equals(cname)) {
232: m_key_combo.setSelectedIndex(index);
233: return;
234: }
235: }
236: m_key_combo.setSelectedIndex(0);
237: }
238:
239: /**
240: * Controller for this view
241: */
242: private class ColorDefinitionController {
243: private boolean m_silent = false;
244:
245: public ColorDefinitionController() {
246: m_key_combo.addActionListener(new ComboChangedAction());
247: ColorSelectorUtils.addActionListener(m_color_well,
248: new ColorWellClicked());
249: m_factor_spinner
250: .addChangeListener(new ColorChangedAction());
251: m_bright_spinner
252: .addChangeListener(new ColorChangedAction());
253: }
254:
255: public void setSilent(boolean silent) {
256: m_silent = silent;
257: }
258:
259: public class ComboChangedAction implements ActionListener {
260: public void actionPerformed(ActionEvent evt) {
261: boolean silent = m_silent;
262: if (!silent) {
263: setSilent(true);
264:
265: m_color_prop.setColorKey(getSelectedColorKey());
266: if (!m_color_prop.isConstant()) {
267: ColorSelectorUtils.setColor(m_color_well,
268: m_color_prop.getColor());
269: }
270: setSilent(silent);
271: }
272: }
273: }
274:
275: public class ColorChangedAction implements ChangeListener {
276: public void stateChanged(ChangeEvent e) {
277: //
278:
279: }
280: }
281:
282: public class ColorWellClicked implements ActionListener {
283: public void actionPerformed(ActionEvent evt) {
284: boolean silent = m_silent;
285: if (!silent) {
286: setSilent(true);
287: m_key_combo.setSelectedIndex(0);
288: setSilent(silent);
289: }
290: }
291: }
292: }
293:
294: /**
295: * Used so we don't have to instantiate in Integer key everytime we want to
296: * lookup a ColorCellValue
297: */
298: public static class ColorLookup {
299: int key;
300:
301: public int hashCode() {
302: return key;
303: }
304: }
305:
306: public static class ColorCellValue {
307: String m_color_name;
308: Color m_color;
309: ColorLookup m_color_key = new ColorLookup();
310: private static HashMap m_color_icons = new HashMap();
311:
312: /**
313: * ctor
314: */
315: public ColorCellValue(String cname, Color color) {
316: m_color_name = cname;
317: m_color = color;
318: if (m_color_name == null)
319: m_color_name = "constant";
320: }
321:
322: public boolean equals(Object obj) {
323: return m_color_name.equals(obj.toString());
324: }
325:
326: public String getName() {
327: return m_color_name;
328: }
329:
330: public Icon getIcon() {
331: if (m_color == null)
332: return null;
333:
334: m_color_key.key = m_color.getRGB();
335: Icon icon = (Icon) m_color_icons.get(m_color_key);
336: if (icon == null) {
337: int width = 12;
338: int height = 12;
339: BufferedImage bimage = new BufferedImage(width, height,
340: BufferedImage.TYPE_INT_RGB);
341: Graphics2D bg = bimage.createGraphics();
342:
343: bg.setColor(m_color);
344: bg.fillRect(0, 0, width, height);
345: bg.setColor(Color.black);
346: bg.drawRect(0, 0, width - 1, height - 1);
347:
348: bg.dispose();
349: icon = new ImageIcon(bimage);
350: m_color_icons.put(new Integer(m_color.getRGB()), icon);
351: }
352: return icon;
353: }
354:
355: public String toString() {
356: return m_color_name;
357: }
358: }
359:
360: /**
361: * Line Renderer
362: */
363: public static class ColorCellRenderer extends JLabel implements
364: ListCellRenderer {
365:
366: public ColorCellRenderer() {
367: // must set or the background color won't show
368: setOpaque(true);
369: setBorder(javax.swing.BorderFactory.createEmptyBorder(1, 2,
370: 1, 0));
371: }
372:
373: public Component getListCellRendererComponent(JList list,
374: Object value, int index, boolean isSelected,
375: boolean cellHasFocus) {
376: ColorCellValue ccv = (ColorCellValue) value;
377: if (ccv == null) {
378: setIcon(null);
379: setText("");
380: } else {
381: setIcon(ccv.getIcon());
382: setText(ccv.getName());
383: }
384:
385: if (isSelected) {
386: setBackground(UIManager
387: .getColor("ComboBox.selectionBackground"));
388: setForeground(UIManager
389: .getColor("ComboBox.selectionForeground"));
390: } else {
391: setBackground(UIManager.getColor("ComboBox.background"));
392: setForeground(UIManager.getColor("ComboBox.foreground"));
393: }
394: return this;
395: }
396: }
397:
398: }
|