1 /*
2 * (C) 2002 David Carr david@carr.name
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 package net.sourceforge.mflow.config;
20
21 import java.awt.BorderLayout;
22 import java.awt.Component;
23 import java.awt.Frame;
24 import java.awt.GridLayout;
25 import java.awt.Label;
26 import java.beans.BeanInfo;
27 import java.beans.Beans;
28 import java.beans.IntrospectionException;
29 import java.beans.Introspector;
30 import java.beans.PropertyChangeEvent;
31 import java.beans.PropertyChangeListener;
32 import java.beans.PropertyDescriptor;
33 import java.beans.PropertyEditor;
34 import java.beans.PropertyEditorManager;
35 import java.beans.PropertyVetoException;
36 import java.lang.reflect.InvocationTargetException;
37 import java.lang.reflect.Method;
38 import java.util.logging.Logger;
39
40 import javax.swing.JDialog;
41 import javax.swing.JPanel;
42 import javax.swing.WindowConstants;
43
44 import net.sourceforge.mflow.api.MsgFlowComponent;
45
46 /***
47 * A dialog to allow a shared configuration dialog for JavaBeans. As long as a component exposes its properties properly and provides a custom editor where needed, this configuration dialog should be all that is needed.
48 *
49 * @author <a href="mailto:david@carr.name">David Carr</a>
50 * @version $Revision: 1.4 $
51 * @todo either ditch or rewrite this class... it's ugly
52 */
53 public class DefaultBeanConfigDialog
54 extends JDialog
55 implements PropertyChangeListener {
56 /***
57 * Private reference to the owner of this dialog
58 */
59 // private Frame mOwner;
60 /***
61 * Private storage for the JavaBean that this dialog is editting
62 */
63 private Object comp;
64
65 /***
66 * Private storage for a reference to the Logger
67 */
68 private static Logger log =
69 Logger.getLogger(DefaultBeanConfigDialog.class.getName());
70
71 /***
72 * Private storage of the properties of the bean
73 */
74 private PropertyDescriptor properties[];
75 /***
76 * Private storage of the editors for the bean
77 */
78 private PropertyEditor editors[];
79 /***
80 * Privates storage of the property values
81 */
82 private Object values[];
83 /***
84 * Private storage for the components used to view/edit the properties
85 */
86 private Component views[];
87 /***
88 * Private storage for the displayed for the properties
89 */
90 private Label labels[];
91
92 /***
93 * Constructor taking a JavaBean and a Frame to own the dialog. Initializes the UI.
94 *
95 * @param comp the JavaBean
96 * @param owner the owner of the dialog
97 */
98 public DefaultBeanConfigDialog(Object comp, Frame owner) {
99 super(
100 owner,
101 (comp instanceof MsgFlowComponent)
102 ? "Properties - " + ((MsgFlowComponent) comp).getName()
103 : "Properties - "
104 + comp.getClass().getName().substring(
105 comp.getClass().getName().lastIndexOf('.') + 1));
106 this.comp = comp;
107 // mOwner = owner;
108 JPanel propPane = new JPanel(new GridLayout(0, 2));
109 getContentPane().setLayout(new BorderLayout());
110 getContentPane().add(propPane, BorderLayout.NORTH);
111 Class c = this.comp.getClass();
112 BeanInfo bi = null;
113 try {
114 bi = Introspector.getBeanInfo(c);
115 } catch (IntrospectionException ie) {
116 log.throwing(
117 "DefaultBeanConfigDialog",
118 "DefaultBeanConfigDialog(comp, owner)",
119 ie);
120 return;
121 }
122 this.properties = bi.getPropertyDescriptors();
123 this.editors = new PropertyEditor[this.properties.length];
124 this.values = new Object[this.properties.length];
125 this.views = new Component[this.properties.length];
126 this.labels = new Label[this.properties.length];
127
128 for (int i = 0; i < this.properties.length; i++) {
129 PropertyDescriptor pd = this.properties[i];
130 if (pd.isHidden() || pd.isExpert()) {
131 continue;
132 }
133 String name = pd.getDisplayName();
134 Class type = pd.getPropertyType();
135 Method getter = pd.getReadMethod();
136 Method setter = pd.getWriteMethod();
137 if (getter == null || setter == null) {
138 continue;
139 }
140 Object args[] = {};
141 Object value = null;
142 try {
143 value = getter.invoke(comp, args);
144 } catch (IllegalAccessException iae) {
145 continue;
146 } catch (InvocationTargetException ite) {
147 continue;
148 }
149 this.values[i] = value;
150
151 PropertyEditor pe = null;
152 Class editor = pd.getPropertyEditorClass();
153 if (editor != null) {
154 try {
155 pe = (PropertyEditor) editor.newInstance();
156 } catch (InstantiationException ie) {
157 log.throwing(
158 "DefaultBeanConfigDialog",
159 "DefaultBeanConfigDialog(comp, owner)",
160 ie);
161 } catch (IllegalAccessException iae) {
162 log.throwing(
163 "DefaultBeanConfigDialog",
164 "DefaultBeanConfigDialog(comp, owner)",
165 iae);
166 }
167 }
168 if (pe == null) {
169 pe = PropertyEditorManager.findEditor(type);
170 }
171 this.editors[i] = pe;
172 if (pe == null) {
173 continue;
174 }
175 if (value == null) {
176 continue;
177 }
178 pe.setValue(value);
179 pe.addPropertyChangeListener(this);
180 Component view = null;
181 if (pe.isPaintable() && pe.supportsCustomEditor()) {
182 view = new PropertyCanvas(this, pe);
183 } else if (pe.getTags() != null) {
184 view = new PropertySelector(pe);
185 } else if (pe.getAsText() != null) {
186 view = new PropertyText(pe);
187 } else {
188 continue;
189 }
190 this.labels[i] = new Label(name, Label.RIGHT);
191 propPane.add(this.labels[i]);
192
193 this.views[i] = view;
194 propPane.add(this.views[i]);
195 }
196 setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
197 pack();
198 }
199
200 /***
201 * Updates the UI and properties as needed
202 *
203 * @param evt the PropertyChangeEvent
204 */
205 public synchronized void propertyChange(PropertyChangeEvent evt) {
206 if (evt.getSource() instanceof PropertyEditor) {
207 PropertyEditor editor = (PropertyEditor) evt.getSource();
208 for (int i = 0; i < this.editors.length; i++) {
209 if (this.editors[i] == editor) {
210 PropertyDescriptor property = this.properties[i];
211 Object value = editor.getValue();
212 this.values[i] = value;
213 Method setter = property.getWriteMethod();
214 try {
215 Object args[] = { value };
216 args[0] = value;
217 setter.invoke(this.comp, args);
218 } catch (InvocationTargetException ex) {
219 if (ex.getTargetException() instanceof PropertyVetoException) {
220 System.err.println(
221 "WARNING: Vetoed; reason is: "
222 + ex.getTargetException().getMessage());
223 } else {
224 throw new RuntimeException(
225 "InvocationTargetException while updating "
226 + property.getName(),
227 ex.getTargetException());
228 }
229 } catch (Exception ex) {
230 throw new RuntimeException(
231 "Unexpected exception while updating " + property.getName(),
232 ex);
233 }
234 if (this.views[i] != null
235 && this.views[i] instanceof PropertyCanvas) {
236 this.views[i].repaint();
237 }
238 break;
239 }
240 }
241 }
242
243 for (int i = 0; i < this.properties.length; i++) {
244 Object o;
245 try {
246 Method getter = this.properties[i].getReadMethod();
247 Object args[] = {};
248 o = getter.invoke(this.comp, args);
249 } catch (Exception ex) {
250 o = null;
251 }
252 if (o == this.values[i] || (o != null && o.equals(this.values[i]))) {
253 continue;
254 }
255 this.values[i] = o;
256 if (this.editors[i] == null) {
257 continue;
258 }
259 this.editors[i].setValue(o);
260 if (this.views[i] != null) {
261 this.views[i].repaint();
262 }
263 }
264
265 if (Beans.isInstanceOf(this.comp, Component.class)) {
266 ((Component) (Beans.getInstanceOf(this.comp, Component.class))).repaint();
267 }
268 }
269 }
This page was automatically generated by Maven