View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans-Common.
5    *
6    * CosyBeans-Common is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * CosyBeans-Common is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with CosyBeans-Common.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package com.cosylab.gui.property.editors;
21  
22  import java.awt.Color;
23  import java.awt.Component;
24  import java.awt.Graphics;
25  import java.awt.event.ActionEvent;
26  import java.awt.event.ActionListener;
27  import java.lang.reflect.InvocationTargetException;
28  import java.util.HashMap;
29  import java.util.Map;
30  
31  import javax.swing.DefaultComboBoxModel;
32  import javax.swing.DefaultListCellRenderer;
33  import javax.swing.JColorChooser;
34  import javax.swing.JList;
35  
36  import com.cosylab.gui.components.SimpleButton;
37  import com.cosylab.gui.components.SimpleComboBox;
38  import com.cosylab.gui.components.util.ColorHelper;
39  import com.cosylab.gui.components.util.CosyUIElements;
40  import com.cosylab.gui.components.util.FontHelper;
41  
42  
43  /**
44   * @author <a href="mailto:miha.kadunc@cosylab.com">Miha Kadunc</a>
45   * @version $id$
46   */
47  public class ColorEditor extends SimpleComboBox implements PropertyEditor {
48      /**
49       * Both drop-down selection and button for the dialog.
50       */
51      public static final int MODE_BOTH = 0;
52  
53      /**
54       * Only the drop-down selection
55       */
56      public static final int MODE_COMBO = 1;
57      private int mode = -1;
58      private Map map = null;
59      private Color value = null;
60      private SimpleButton extendButton = null;
61  
62      /**
63       */
64      public ColorEditor() {
65          this(null);
66      }
67  
68      /**
69       * @param defaultColor Color
70       */
71      public ColorEditor(Color defaultColor) {
72          super();
73          initialize();
74          setPropertyValue(defaultColor);
75      }
76  
77      /**
78       * @return Object
79       * @see com.cosylab.gui.property.editors.PropertyEditor#getPropertyValue()
80       */
81      public Object getPropertyValue() {
82          return value;
83      }
84  
85      /**
86       * @param value Object
87       * @return boolean
88       * @see com.cosylab.gui.property.editors.PropertyEditor#setPropertyValue(Object)
89       */
90      public boolean setPropertyValue(Object value) {
91          if (value instanceof Color) {
92              Color daNew = (Color) value;
93              Color old = this.value;
94              this.value = daNew;
95              
96              if (map.containsValue(daNew)) {
97                  setSelectedItem(getKeyForValue(map, daNew));
98              } else {
99                  setSelectedItem(null);
100             }
101 
102             if ((daNew != null) && (daNew.getBlue() < 130) &&
103                     (daNew.getRed() < 130) && (daNew.getGreen() < 130)) {
104                 setForeground(Color.WHITE);
105             } else {
106                 setForeground(Color.BLACK);
107             }
108 
109             extendButton.repaint();
110             firePropertyChange(PROPERTY_VALUE_NAME, old, daNew);
111 
112             return true;
113         }
114 
115         return false;
116     }
117 
118     public static Object getKeyForValue(Map m, Object value) {
119         Object[] keys = m.keySet().toArray();
120         Object val;
121         int i = 0;
122 
123         while (i < keys.length) {
124             val = m.get(keys[i]);
125 
126             if (val.equals(value)) {
127                 return keys[i];
128             }
129 
130             i++;
131         }
132 
133         return null;
134     }
135 
136     /**
137      * @return String
138      * @see com.cosylab.gui.property.editors.PropertyEditor#getDescription()
139      */
140     public String getDescription() {
141         return null;
142     }
143 
144     /**
145      * @param description String
146      * @see com.cosylab.gui.property.editors.PropertyEditor#setDescription(String)
147      */
148     public void setDescription(String description) {
149     }
150 
151     /**
152      * @return PropertyEditor
153      * @see com.cosylab.gui.property.editors.PropertyEditor#getEditor()
154      */
155     public PropertyEditor getPropertyEditor() {
156         return null;
157     }
158 
159     private void initialize() {
160         setBorder(CosyUIElements.getPlainBorder(false));
161         addActionListener(new ActionListener() {
162                 /**
163                  * @see java.awt.event.ActionListener#actionPerformed(ActionEvent)
164                  */
165                 public void actionPerformed(ActionEvent e) {
166                     Color daNew = (Color) map.get(getSelectedItem());
167                     setPropertyValue(daNew);
168                 }
169             });
170         initializeComboListeners();
171         extendButton = new SimpleButton("...");
172         extendButton.setBorder(CosyUIElements.getPlainBorder(true));
173         extendButton.setPressedBorder(null);
174         extendButton.setActionMode(SimpleButton.FAST_ACTION_MODE);
175         extendButton.addActionListener(new ActionListener() {
176                 public void actionPerformed(ActionEvent e) {
177                     Color c = JColorChooser.showDialog(ColorEditor.this,
178                             "Choose the desired color", value);
179                     setPropertyValue(c);
180                 }
181             });
182         setMode(MODE_BOTH);
183         setColorMap(getJavaColorMap());
184     }
185 
186     private void initializeComboListeners() {
187     }
188 
189     public void setMode(int mode) {
190         if (mode != this.mode) {
191             int old = this.mode;
192             this.mode = mode;
193 
194             if (mode == MODE_BOTH) {
195                 setUI(new ColorEditorUI());
196             } else if (mode == MODE_COMBO) {
197                 setStyle(SimpleComboBox.DROP_DOWN_STYLE);
198             }
199 
200             firePropertyChange("mode", old, mode);
201         }
202     }
203 
204     public void setColorMap(Map colorMap) {
205         map = colorMap;
206         setModel(new DefaultComboBoxModel(colorMap.keySet().toArray()));
207         setRenderer(new ColorCellRenderer(colorMap));
208         setSelectedIndex(0);
209     }
210 
211     /**
212      * @return Map
213      */
214     public static Map getCosyColorMap() {
215         HashMap ret = new HashMap();
216         String[] names = ColorHelper.COLOR_NAMES;
217 
218         for (int i = 0; i < names.length; i++) {
219             try {
220                 ret.put(names[i],
221                     ColorHelper.class.getMethod("get" + names[i], new Class[0])
222                                      .invoke(null, new Object[0]));
223             } catch (IllegalAccessException e) {
224             } catch (InvocationTargetException e) {
225             } catch (NoSuchMethodException e) {
226             }
227         }
228 
229         return ret;
230     }
231 
232     /**
233      * @return Map
234      */
235     public static Map getJavaColorMap() {
236         HashMap ret = new HashMap();
237         String[] names = ColorHelper.JAVA_COLOR_NAMES;
238 
239         for (int i = 0; i < names.length; i++) {
240             try {
241                 ret.put(names[i], Color.class.getField(names[i]).get(null));
242             } catch (IllegalAccessException e) {
243             } catch (NoSuchFieldException e) {
244             }
245         }
246 
247         return ret;
248     }
249 
250     /**
251      * @see javax.swing.JComponent#paintComponent(Graphics)
252      */
253     protected void paintComponent(Graphics g) {
254         g.setColor(getBackground());
255         g.fillRect(0, 0, getWidth(), getHeight());
256         super.paintComponent(g);
257     }
258 
259     public class ColorEditorUI extends SimpleComboBox.DropComboBoxUI {
260         /**
261          * @see com.cosylab.gui.components.SimpleComboBox.DropComboBoxUI#getDropButton()
262          */
263         protected SimpleButton getDropButton() {
264             return extendButton;
265         }
266     }
267 
268     /**
269     *
270     *
271     * @author  Miha Kadunc (miha.kadunc@cosylab.com)
272     * @version @@VERSION@@
273     */
274     public class ColorCellRenderer extends DefaultListCellRenderer {
275         private Map colorMap = null;
276 
277         /**
278          * @param valueToColorMap Map
279          */
280         public ColorCellRenderer(Map valueToColorMap) {
281             colorMap = valueToColorMap;
282             getInsets().left = 10;
283             setFont(FontHelper.getDefaultFont());
284         }
285 
286         /**
287          * @param list JList
288          * @param value Object
289          * @param index int
290          * @param isSelected boolean
291          * @param cellHasFocus boolean
292          * @return Component
293          * @see javax.swing.DefaultListCellRenderer#getListCellRendererComponent(JList, Object, int, boolean, boolean)
294          */
295         public Component getListCellRendererComponent(JList list, Object value,
296             int index, boolean isSelected, boolean cellHasFocus) {
297             super.getListCellRendererComponent(list, value, index, isSelected,
298                 cellHasFocus);
299 
300             Color bkg = (Color)colorMap.get(value);
301             if (bkg==null) bkg=ColorEditor.this.value; 
302             setBackground(bkg);
303 
304             if ((bkg != null) && (bkg.getBlue() < 130) && (bkg.getRed() < 130) &&
305                     (bkg.getGreen() < 130)) {
306                 setForeground(Color.WHITE);
307             } else {
308                 setForeground(Color.BLACK);
309             }
310 
311             return this;
312         }
313     }
314 }