1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.gui.components.customizer;
21
22 import java.awt.BorderLayout;
23 import java.awt.Component;
24 import java.awt.FlowLayout;
25 import java.awt.Font;
26 import java.awt.font.FontRenderContext;
27 import java.beans.BeanInfo;
28 import java.beans.Customizer;
29 import java.beans.IntrospectionException;
30 import java.beans.Introspector;
31 import java.beans.PropertyChangeEvent;
32 import java.beans.PropertyChangeListener;
33 import java.beans.PropertyDescriptor;
34 import java.util.ArrayList;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.LinkedHashSet;
38 import java.util.List;
39
40 import javax.swing.AbstractAction;
41 import javax.swing.AbstractListModel;
42 import javax.swing.JButton;
43 import javax.swing.JDialog;
44 import javax.swing.JList;
45 import javax.swing.JPanel;
46 import javax.swing.JScrollPane;
47 import javax.swing.JSplitPane;
48 import javax.swing.event.ListSelectionEvent;
49 import javax.swing.event.ListSelectionListener;
50
51
52
53
54
55
56
57
58
59
60
61 public abstract class AbstractCustomizerPanel extends JSplitPane implements Customizer {
62
63 private Object bean;
64 private JDialog dialog;
65 private LinkedHashSet<Customizer> customizers;
66 private HashMap<String, Component> aspectToComponent;
67 private AspectModel model;
68 private JList list;
69 private JScrollPane rightPanel;
70
71 class AspectModel extends AbstractListModel {
72 private static final long serialVersionUID = 1L;
73 private List<String> aspects= new ArrayList<String>();
74
75
76
77
78 public AspectModel() {
79 }
80
81
82
83
84 public int getSize() {
85 return aspects.size();
86 }
87
88
89
90
91 public Object getElementAt(int index) {
92 return aspects.get(index);
93 }
94
95 public void add(String name) {
96 if (aspects.contains(name)) {
97 return;
98 }
99 aspects.add(name);
100 Collections.sort(aspects);
101 fireContentsChanged(this,0,getSize()-1);
102 }
103
104 }
105
106
107
108
109
110 public AbstractCustomizerPanel() {
111 initialize();
112 }
113
114
115
116
117
118
119
120
121 public void addCustomizer(String aspect, Customizer customizer) {
122
123 model.add(aspect);
124 customizers.add(customizer);
125 customizer.addPropertyChangeListener(new PropertyChangeListener() {
126
127 public void propertyChange(PropertyChangeEvent evt) {
128 firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt
129 .getNewValue());
130
131 }
132 });
133
134 aspectToComponent.put(aspect, (Component) customizer);
135
136
137 Font f = (new JScrollPane()).getFont();
138 int l = (int) f.getStringBounds(aspect, new FontRenderContext(f.getTransform(), false, false)).getWidth();
139 l += 25;
140 if (getDividerLocation() < l) setDividerLocation(l);
141 }
142
143
144
145
146
147
148
149 public void addCustomizerPlaceholder(String aspect, JPanel panel) {
150 model.add(aspect);
151 aspectToComponent.put(aspect, panel);
152 }
153
154
155
156
157
158
159
160 public void addCustomizerTable(String aspect, String... properties) {
161 addCustomizer(aspect, CustomizerFactory.createCustomizer(properties));
162 }
163
164
165
166
167
168
169
170 public void addCustomizerTable(String aspect, PropertyDescriptor... properties) {
171 addCustomizer(aspect, CustomizerFactory.createCustomizer(properties));
172 }
173
174
175
176
177
178
179 public void addCustomizer(AbstractCustomizerPanel abstractCustomizer) {
180
181 for (int i=0; i< abstractCustomizer.model.getSize(); i++) {
182 model.add((String)abstractCustomizer.model.getElementAt(i));
183 }
184 this.aspectToComponent.putAll(abstractCustomizer.aspectToComponent);
185
186
187
188 for (Customizer customizer : abstractCustomizer.customizers) {
189 this.customizers.add(customizer);
190
191 }
192
193
194
195 abstractCustomizer.addPropertyChangeListener(new PropertyChangeListener() {
196
197 public void propertyChange(PropertyChangeEvent evt) {
198 firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt
199 .getNewValue());
200
201 }
202 });
203
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221 public static AbstractCustomizerPanel findCustomizer(Object bean) {
222
223
224 Class beanType = bean.getClass();
225 Class customizerClass;
226 AbstractCustomizerPanel c=null;
227
228 try {
229 BeanInfo beanInfo = Introspector.getBeanInfo(beanType);
230
231 customizerClass = beanInfo.getBeanDescriptor().getCustomizerClass();
232
233 if (customizerClass != null) {
234
235
236 if (AbstractCustomizerPanel.class.isAssignableFrom(customizerClass)) {
237 try {
238 c= (AbstractCustomizerPanel) customizerClass.newInstance();
239 } catch (InstantiationException e) {
240 e.printStackTrace();
241 } catch (IllegalAccessException e) {
242 e.printStackTrace();
243 }
244 }
245 }
246
247 } catch (IntrospectionException e) {
248 e.printStackTrace();
249 }
250
251 if (c == null) {
252
253 try {
254
255 customizerClass = Class.forName(beanType.getName() + "Customizer");
256 if (customizerClass != null) {
257
258
259 if (AbstractCustomizerPanel.class.isAssignableFrom(customizerClass)) {
260 try {
261 c= (AbstractCustomizerPanel) customizerClass.newInstance();
262 } catch (InstantiationException e) {
263 e.printStackTrace();
264 } catch (IllegalAccessException e) {
265 e.printStackTrace();
266 }
267 }
268
269 }
270 } catch (ClassNotFoundException e) {
271 e.printStackTrace();
272 }
273 }
274 if (c!=null) {
275 c.setObject(bean);
276 }
277 return c;
278 }
279
280 private void initialize() {
281 customizers = new LinkedHashSet<Customizer>();
282 model= new AspectModel();
283 aspectToComponent = new HashMap<String, Component>();
284 list = new JList();
285 list.setModel(model);
286 list.addListSelectionListener(new ListSelectionListener() {
287
288 public void valueChanged(ListSelectionEvent e) {
289
290 Component component = aspectToComponent.get(list.getSelectedValue());
291
292 if (component != null) {
293 rightPanel.setViewportView(component);
294 }
295
296 }
297 });
298
299 setLeftComponent(new JScrollPane(list));
300
301 rightPanel= new JScrollPane();
302 setRightComponent(rightPanel);
303 setSize(500,300);
304 setDividerLocation(30);
305 }
306
307
308
309
310
311 public void setObject(Object bean) {
312 this.bean = bean;
313
314 for (Customizer customizer : customizers) {
315 customizer.setObject(bean);
316 }
317
318 if (getName()==null) {
319 String s= bean.getClass().getName();
320 int i= s.lastIndexOf('.');
321 if (i>-1 && i+1<s.length()) {
322 setName(s.substring(i+1));
323 } else {
324 setName(s);
325 }
326 }
327 }
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342 public JDialog showDialog() {
343 return showDialog(bean instanceof Component ? (Component) bean : null);
344 }
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362 public JDialog showDialog(Component c) {
363 if (dialog == null) {
364 dialog = new JDialog();
365 dialog.setTitle(getName() + " Customizer");
366 dialog.setModal(false);
367 dialog.setSize(getSize().width + dialog.getInsets().left
368 + dialog.getInsets().right, getSize().height + dialog.getInsets().top
369 + dialog.getInsets().bottom);
370 dialog.getContentPane().setLayout(new BorderLayout());
371 dialog.getContentPane().add(this, BorderLayout.CENTER);
372 JPanel p = new JPanel();
373 p.setLayout(new FlowLayout(FlowLayout.RIGHT));
374 p.add(new JButton(new AbstractAction("Close") {
375 private static final long serialVersionUID = 1L;
376 public void actionPerformed(java.awt.event.ActionEvent e) {
377 dialog.dispose();
378 };
379 }));
380 dialog.getContentPane().add(p, BorderLayout.SOUTH);
381 dialog.setLocationRelativeTo(c);
382 }
383
384 dialog.setVisible(false);
385 dialog.setVisible(true);
386 dialog.toFront();
387 return dialog;
388 }
389
390
391
392
393
394 public void closeDialog() {
395 if (dialog != null) {
396 dialog.setVisible(false);
397 }
398 }
399
400
401
402
403
404
405 public void selectAspect(String aspect) {
406 list.setSelectedValue(aspect, true);
407 }
408
409 }