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.Insets;
24  import java.awt.event.FocusAdapter;
25  import java.awt.event.FocusEvent;
26  import java.awt.event.KeyAdapter;
27  import java.awt.event.KeyEvent;
28  import java.lang.reflect.Modifier;
29  
30  import javax.swing.JTextField;
31  
32  import com.cosylab.gui.components.util.ColorHelper;
33  import com.cosylab.util.StringUtilities;
34  
35  /**
36   * A component used for specifyind <code>Class<code> objects.
37   * User can enter the name of the class and upon pressing
38   * enter or on loosing focus the <code>Class</code> instance
39   * is obtained and propertyChange events are fired. If the class name
40   * is invalid, the text in the textField is colored red.
41   * 
42   * @author <a href="mailto:miha.kadunc@cosylab.com">Miha Kadunc</a> 
43   * @version $id$
44   */
45  public class ClassEditor extends JTextField implements PropertyEditor {
46  	public static final String APPLY_MODE_PROPERTY="applyMode";
47  	public static final int APPLY_ON_CHANGE=4;
48  	public static final int APPLY_ON_FOCUS_LOST=2;
49  	public static final int APPLY_ON_ENTER=1;
50  	public static final int APPLY_NEVER=0;
51  	private java.awt.Color errorColor = ColorHelper.getAlarm();
52  	private java.lang.Class fieldUserClass = null;
53  	private java.lang.Class fieldSuperClass = null;
54  	private boolean fieldAllowInterface = true;
55  	/**
56  	 *  
57  	 */
58  	public ClassEditor() {
59  		super();
60  		initialize();
61  	}
62  	/**
63  	 *  
64  	 */
65  	public ClassEditor(Class superClass) {
66  		this();
67  		setSuperClass(superClass);
68  	}
69  
70  	/**
71  	 * Method generated to support the promotion of the errorColor attribute.
72  	 * 
73  	 * @param arg1
74  	 *            java.awt.Color
75  	 */
76  	private void paintField(boolean isError) {
77  		if (isError)
78  			setForeground(getErrorColor());
79  		else
80  			setForeground(Color.black);
81  	}
82  
83  	/**
84  	 * Creation date: (9.1.2002 23:37:31)
85  	 */
86  	private boolean checkClass(Class c) {
87  		try {
88  			if (c == null)
89  				return true;
90  			if ((fieldSuperClass != null)
91  				&& (!(fieldSuperClass.isAssignableFrom(c)))) {
92  				return false;
93  			}
94  			if (!(fieldAllowInterface)
95  				&& ((c.isInterface())
96  					|| (Modifier.isAbstract(c.getModifiers())))) {
97  				return false;
98  			}
99  		} catch (Exception e) {
100 			setUserClass(null);
101 			paintField(true);
102 		}
103 		return true;
104 	}
105 
106 	private void checkText() {
107 		try {
108 			setUserClass(StringUtilities.classFromString(getText()));
109 		} catch (Exception e) {
110 			setUserClass(null);
111 			paintField(true);
112 		}
113 	}
114 	private void initialize() {
115 		addFocusListener(new FocusAdapter() {
116 			/**
117 			 * @see java.awt.event.FocusAdapter#focusLost(FocusEvent)
118 			 */
119 			public void focusLost(FocusEvent e) {
120 				super.focusLost(e);
121 				if ((getApplyMode() & APPLY_ON_FOCUS_LOST)==APPLY_ON_FOCUS_LOST) {
122 					checkText();
123 				}
124 			}
125 
126 		});
127 		addKeyListener(new KeyAdapter() {
128 			/**
129 			 * @see java.awt.event.KeyAdapter#keyTyped(KeyEvent)
130 			 */
131 			public void keyPressed(KeyEvent e) {
132 				if ((e.getKeyCode() == KeyEvent.VK_ENTER)) {
133 					if ((getApplyMode() & APPLY_ON_ENTER)==APPLY_ON_ENTER) {
134 						checkText();
135 						return;
136 					}
137 				} else {
138 					if ((getApplyMode() & APPLY_ON_CHANGE)==APPLY_ON_CHANGE) {
139 						checkText();
140 						return;
141 					}
142 				}
143 				paintField(false);
144 			}
145 		});
146 		setApplyMode(APPLY_ON_ENTER | APPLY_ON_FOCUS_LOST);
147 	}
148 	
149 	/**
150 	 * Gets the allowAbstract.
151 	 * 
152 	 * @return Returns a boolean
153 	 */
154 	public boolean getAllowAbstract() {
155 		return fieldAllowInterface;
156 	}
157 
158 	/**
159 	 * Sets the AllowInterface.
160 	 * 
161 	 * @param AllowInterface
162 	 *            The AllowInterface to set
163 	 */
164 	public void setAllowAbstract(boolean allowInterface) {
165 		fieldAllowInterface = allowInterface;
166 	}
167 
168 	/**
169 	 * Gets the superClass.
170 	 * 
171 	 * @return Returns a java.lang.Class
172 	 */
173 	public java.lang.Class getSuperClass() {
174 		return fieldSuperClass;
175 	}
176 
177 	/**
178 	 * Sets the superClass.
179 	 * 
180 	 * @param superClass
181 	 *            The superClass to set
182 	 */
183 	public void setSuperClass(java.lang.Class superClass) {
184 		fieldSuperClass = superClass;
185 		checkText();
186 	}
187 
188 	/**
189 	 * Gets the UserClass.
190 	 * 
191 	 * @return Returns a java.lang.Class
192 	 */
193 	public java.lang.Class getUserClass() {
194 		return fieldUserClass;
195 	}
196 
197 	/**
198 	 * Sets the userClass.
199 	 * 
200 	 * @param userClass
201 	 *            The userClass to set
202 	 */
203 	private void setUserClass(java.lang.Class userClass) {
204 		if (checkClass(userClass)) {
205 			Class oldValue = fieldUserClass;
206 			if (oldValue==null && userClass==null) return;
207 			if (userClass != null) {
208 				paintField(false);
209 			}
210 			if (oldValue==null || !((oldValue).equals(userClass))) {
211 				fieldUserClass = userClass;
212 				firePropertyChange("userClass", oldValue, fieldUserClass);
213 				firePropertyChange(PROPERTY_VALUE_NAME,oldValue, fieldUserClass);
214 			}
215 			if (userClass!=null) {
216 				internalSetText(userClass.getName(),false);
217 			} else {
218 				internalSetText("",false);
219 			}
220 		} else {
221 			if (userClass!=null) {
222 				internalSetText(userClass.getName(),false);
223 			}
224 			paintField(true);
225 			if (fieldUserClass != null)
226 				setUserClass(null);
227 		}
228 	}
229 
230 	/**
231 	 * Gets the errorColor.
232 	 * 
233 	 * @return Returns a java.awt.Color
234 	 */
235 	public java.awt.Color getErrorColor() {
236 		return errorColor;
237 	}
238 
239 	/**
240 	 * Sets the errorColor.
241 	 * 
242 	 * @param errorColor
243 	 *            The errorColor to set
244 	 */
245 	public void setErrorColor(java.awt.Color errorColor) {
246 		this.errorColor = errorColor;
247 	}
248 
249 	/**
250 	 * @see JTextComponent#setText(String)
251 	 */
252 	public void setText(String t) {
253 		internalSetText(t,true);
254 	}
255 	
256 	private void internalSetText(String t, boolean check) {
257 		super.setText(t);
258 		if (check) {
259 			checkText();
260 		}
261 	}
262 
263 	/**
264 	 * @see ValueEditor#getValue()
265 	 */
266 	public Object getPropertyValue() {
267 		checkText();
268 		return getUserClass();
269 	}
270 
271 	/**
272 	 * @see ValueEditor#setValue(Object)
273 	 */
274 	public boolean setPropertyValue(Object value) {
275 		if (value instanceof Class) {
276 			setUserClass((Class) value);
277 			return true;
278 		}
279 		return false;
280 	}
281 
282 	/**
283 	 * Bugfix for bug 4243496 (versions 1.1.7 - 1.4)
284 	 * 
285 	 * @see JComponent#setMargin(Insets)
286 	 */
287 	public void setMargin(Insets margin) {
288 		if (margin == null) {
289 			super.setMargin(new Insets(0, 2, 0, 2));
290 			return;
291 		}
292 		if (margin.left == 0) {
293 			super.setMargin(
294 				new Insets(margin.top, 2, margin.bottom, margin.right));
295 			return;
296 		}
297 		super.setMargin(margin);
298 	}
299 
300 	/**
301 	 * @see com.cosylab.gui.property.editors.PropertyEditor#getDescription()
302 	 */
303 	public String getDescription() {
304 		return null;
305 	}
306 
307 	/**
308 	 * @see com.cosylab.gui.property.editors.PropertyEditor#getEditor()
309 	 */
310 	public PropertyEditor getEditor() {
311 		return this;
312 	}
313 
314 	/**
315 	 * @see com.cosylab.gui.property.editors.PropertyEditor#setDescription(String)
316 	 */
317 	public void setDescription(String description) {
318 	}
319 	
320 	public void setApplyMode(int mode) {
321 		putClientProperty(APPLY_MODE_PROPERTY,new Integer(mode));
322 	}
323 	
324 	public int getApplyMode(){
325 		return ((Integer)getClientProperty(APPLY_MODE_PROPERTY)).intValue();
326 	}
327 }