1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.gui.adapters;
21
22 import java.awt.Component;
23 import java.awt.Dimension;
24 import java.awt.GridBagConstraints;
25 import java.awt.GridBagLayout;
26 import java.awt.Insets;
27 import java.awt.event.ActionEvent;
28 import java.awt.event.ActionListener;
29 import java.awt.event.MouseAdapter;
30 import java.awt.event.MouseEvent;
31 import java.beans.Customizer;
32 import java.beans.PropertyChangeEvent;
33 import java.beans.PropertyChangeListener;
34 import java.beans.PropertyVetoException;
35
36 import javax.swing.DefaultComboBoxModel;
37 import javax.swing.DefaultListCellRenderer;
38 import javax.swing.DefaultListModel;
39 import javax.swing.JButton;
40 import javax.swing.JComboBox;
41 import javax.swing.JFrame;
42 import javax.swing.JLabel;
43 import javax.swing.JList;
44 import javax.swing.JPanel;
45 import javax.swing.JScrollPane;
46 import javax.swing.ScrollPaneConstants;
47
48 import com.cosylab.gui.components.util.IconHelper;
49 import com.cosylab.gui.displayers.ConvertibleDisplayer;
50
51
52
53
54
55
56
57
58
59
60
61 public class ConverterCustomizer extends JPanel implements Customizer {
62 private static final long serialVersionUID = 1L;
63
64 private class AvailableCellRenderer extends DefaultListCellRenderer {
65
66 private static final long serialVersionUID = 1L;
67
68 public AvailableCellRenderer() {
69 setOpaque(true);
70 }
71
72 public Component getListCellRendererComponent(JList list, Object value,
73 int index, boolean isSelected, boolean cellHasFocus) {
74
75 String name = ((Class) value).getSimpleName();
76 if (name != null && name.endsWith("Converter")) name = name.substring(0, name.lastIndexOf("Converter"));
77
78 return super.getListCellRendererComponent(list,name,index,isSelected,cellHasFocus);
79 }
80
81 }
82
83 private JComboBox functionsList = null;
84
85 private JList selectedFunctionsList = null;
86
87 private DefaultComboBoxModel functionModel;
88
89 private DefaultListModel selectedModel;
90
91 private JPanel buttonPanel = null;
92
93 private JLabel functionsLabel = null;
94
95 private JButton addButton = null, removeButton = null;
96
97 private JButton editButton = null;
98
99 private ConvertibleDisplayer convertibleDisplayer = null;
100
101 protected Converter converter = null;
102
103 private JScrollPane scrollPane = null;
104
105 private Class<Converter>[] converters;
106
107
108
109
110
111
112 @SuppressWarnings({ "unchecked" })
113 public ConverterCustomizer() {
114 this(new Class[] { IdentityConverter.class, MultiplierConverter.class, LinearConverter.class,
115 PotentialConverter.class, ExponentialConverter.class, LogarithmicConverter.class
116 });
117 }
118
119
120
121
122
123
124 @SuppressWarnings("unchecked")
125 public ConverterCustomizer(Class<? extends Converter>[] converters) {
126 this.converters = (Class<Converter>[]) converters;
127 initialize();
128 }
129
130 private void initialize() {
131 setLayout(new GridBagLayout());
132 add(getFunctionsList(), new GridBagConstraints(0, 0, 2, 1, 1, 0, GridBagConstraints.NORTHEAST, GridBagConstraints.HORIZONTAL, new Insets(7, 7, 2, 4), 1, 1));
133 add(getAddButton(), new GridBagConstraints(2, 0, 1, 1, 0, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(7, 2, 2, 7), 0, 0));
134 add(getScrollPane(), new GridBagConstraints(0, 1, 3, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(4, 7, 4, 7), 1, 1));
135 add(getButtonPanel(), new GridBagConstraints(0, 2, 3, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(2, 7, 4, 7), 0, 0));
136 add(getFunctionsLabel(), new GridBagConstraints(0, 3, 3, 1, 1, 0, GridBagConstraints.SOUTHWEST, GridBagConstraints.HORIZONTAL, new Insets(4, 7, 7, 7), 0, 0));
137 }
138
139
140
141
142
143
144 public void setObject(Object bean) {
145 if (!(bean instanceof ConvertibleDisplayer)) {
146 throw new IllegalArgumentException("Bean " + bean.getClass()
147 + " must implement ConvertibleDisplayer!");
148 }
149 convertibleDisplayer = (ConvertibleDisplayer) bean;
150
151 if (convertibleDisplayer.getConverter() != null) {
152 setConverter(convertibleDisplayer.getConverter());
153 }
154
155 convertibleDisplayer.addPropertyChangeListener(
156 ConvertibleDisplayer.CONVERTER_PROPERTY, new PropertyChangeListener() {
157 public void propertyChange(PropertyChangeEvent evt) {
158 if (!ConvertibleDisplayer.CONVERTER_PROPERTY.equals(evt
159 .getPropertyName()))
160 return;
161 setConverter(convertibleDisplayer.getConverter());
162 }
163 });
164 }
165
166 private void applyUsedConverters(Converter... converters) {
167 selectedModel.clear();
168 for (Converter c : converters) {
169 if (c != null)
170 selectedModel.addElement(c);
171 }
172
173 applySelectedFunctions();
174 }
175
176 private JPanel getButtonPanel() {
177 if (buttonPanel == null) {
178 buttonPanel = new JPanel();
179 buttonPanel.setLayout(new GridBagLayout());
180
181 buttonPanel.add(getEditButton(), new GridBagConstraints(0, 0, 1, 1,
182 1, 1, GridBagConstraints.WEST, GridBagConstraints.NONE,
183 new Insets(0, 0, 0, 5), 0, 0));
184 buttonPanel.add(getRemoveButton(), new GridBagConstraints(1, 0, 1,
185 1, 1, 1, GridBagConstraints.EAST,
186 GridBagConstraints.NONE, new Insets(0, 5, 0, 0), 0, 0));
187 buttonPanel.setMaximumSize(new Dimension(100, 100));
188
189 }
190 return buttonPanel;
191 }
192
193 private JButton getEditButton() {
194 if (editButton == null) {
195 editButton = new JButton("Edit");
196 editButton.setEnabled(false);
197 editButton.setToolTipText("Edit function");
198
199
200
201 editButton.addActionListener(new ActionListener() {
202 public void actionPerformed(ActionEvent e) {
203 int i = selectedFunctionsList.getSelectedIndex();
204 if (i >= 0)
205 edit((Converter) selectedModel.get(i));
206 refreshSelectedFunctionsList();
207 applyFunctionsText();
208 }
209 });
210 }
211
212 return editButton;
213 }
214
215 private JButton getAddButton() {
216 if (addButton == null) {
217 addButton = new JButton("Add", IconHelper.createIcon("icons/navigation/Plus16.gif"));
218 addButton.setToolTipText("Add function");
219 addButton.setMinimumSize(new Dimension(100, 22));
220 addButton.setMaximumSize(new Dimension(200, 22));
221 addButton.setPreferredSize(new Dimension(100, 22));
222 addButton.addActionListener(new ActionListener() {
223 public void actionPerformed(ActionEvent e) {
224 addToSelectedList();
225 }
226 });
227 }
228
229 return addButton;
230 }
231
232
233
234
235
236
237 public Converter getConverter() {
238 return converter;
239 }
240
241
242
243
244
245
246 public void setConverter(Converter c) {
247 if (converter != null && converter.equals(c) || (converter == null && c == null))
248 return;
249 Converter old = converter;
250 converter = c;
251 if (c instanceof ConverterChain) {
252 applyUsedConverters(((ConverterChain) c).getConverters());
253 } else {
254 applyUsedConverters(c);
255 }
256
257 firePropertyChange(ConvertibleDisplayer.CONVERTER_PROPERTY, old, converter);
258 }
259
260 private JLabel getFunctionsLabel() {
261 if (functionsLabel == null) {
262 functionsLabel = new JLabel();
263 Dimension d = new Dimension(200, 21);
264 functionsLabel.setMaximumSize(d);
265 functionsLabel.setPreferredSize(d);
266 functionsLabel.setMinimumSize(new Dimension(100, 10));
267 }
268
269 return functionsLabel;
270 }
271
272 private JComboBox getFunctionsList() {
273 if (functionsList == null) {
274 functionsList = new JComboBox();
275 functionModel = new DefaultComboBoxModel();
276 for (Class c : converters) {
277 functionModel.addElement(c);
278 }
279 functionsList.setModel(functionModel);
280 functionsList.setRenderer(new AvailableCellRenderer());
281 functionsList.setMinimumSize(new Dimension(100, 21));
282 functionsList.setMaximumSize(new Dimension(200, 21));
283 functionsList.setPreferredSize(new Dimension(100, 21));
284 functionsList.setSelectedIndex(0);
285 functionsList.addMouseListener(new MouseAdapter() {
286 public void mouseClicked(MouseEvent e) {
287 if (e.getClickCount() == 2 && functionsList.isEnabled()) {
288 addToSelectedList();
289 }
290 }
291 });
292 }
293
294 return functionsList;
295 }
296
297 private JButton getRemoveButton() {
298 if (removeButton == null) {
299 removeButton = new JButton("Remove", IconHelper.createIcon("icons/navigation/Minus16.gif"));
300 removeButton.setToolTipText("Remove function");
301
302
303
304 removeButton.addActionListener(new ActionListener() {
305 public void actionPerformed(ActionEvent e) {
306 removeFromSelectedList();
307 }
308 });
309 }
310
311 return removeButton;
312 }
313
314 private void removeFromSelectedList() {
315 Object[] selected = getSelectedFunctionsList().getSelectedValues();
316 if (selected != null) {
317 for (Object o : selected) {
318 selectedModel.removeElement(o);
319 }
320 }
321
322 applySelectedFunctions();
323 }
324
325 private void addToSelectedList() {
326 Class conv = (Class) getFunctionsList().getSelectedItem();
327 if (conv == null)
328 return;
329 Converter c = getConverterFromClass(conv);
330
331 if (c != null) {
332 if (!checkEditable(c) || edit(c)) {
333 selectedModel.addElement(c);
334 }
335 }
336 applySelectedFunctions();
337
338 }
339
340 private void applySelectedFunctions() {
341 int k = selectedModel.size();
342 if (k == 0) {
343 converter = null;
344 } else if (k == 1) {
345 converter = (Converter) selectedModel.get(0);
346 } else {
347 Converter[] c = new Converter[k];
348 for (int i = 0; i < k; i++) {
349 c[i] = (Converter) selectedModel.get(i);
350 }
351 try {
352 converter = new ConverterChain(c);
353 } catch (PropertyVetoException e) {
354 e.printStackTrace();
355 }
356 }
357
358 applyFunctionsText();
359 try {
360 if (this.convertibleDisplayer != null)
361 convertibleDisplayer.setConverter(converter);
362 } catch (PropertyVetoException e) {
363 e.printStackTrace();
364 }
365
366 firePropertyChange(ConvertibleDisplayer.CONVERTER_PROPERTY, null, converter);
367 }
368
369 private void applyFunctionsText() {
370 String s = "INPUT";
371 int k = selectedModel.size();
372 for (int i = 0; i < k; i++) {
373 s = composeFunction((Converter) selectedModel.get(i), s);
374 }
375
376 s = "OUTPUT = " + s;
377
378 getFunctionsLabel().setText(s);
379 getFunctionsLabel().setToolTipText(s);
380 }
381
382 @SuppressWarnings("unchecked")
383 private Converter getConverterFromClass(Class conv) {
384 try {
385 return (Converter) conv.getConstructor().newInstance();
386 } catch (Exception e) {
387 e.printStackTrace();
388 }
389 return null;
390 }
391
392 private JList getSelectedFunctionsList() {
393 if (selectedFunctionsList == null) {
394 selectedFunctionsList = new JList();
395 selectedModel = new DefaultListModel();
396 selectedFunctionsList.setModel(selectedModel);
397 selectedFunctionsList.addMouseListener(new MouseAdapter() {
398 public void mouseClicked(MouseEvent e) {
399 if (e.getClickCount() == 2
400 && selectedFunctionsList.isEnabled()) {
401 edit((Converter) selectedModel.get(getSelectedFunctionsList().getSelectedIndex()));
402 } else if (getSelectedFunctionsList().getSelectedIndex() != -1){
403 if (checkEditable((Converter) selectedModel.get(getSelectedFunctionsList().getSelectedIndex())))
404 getEditButton().setEnabled(true);
405 else
406 getEditButton().setEnabled(false);
407 }
408 }
409 });
410 }
411
412 return selectedFunctionsList;
413 }
414
415 private JScrollPane getScrollPane(){
416 if (scrollPane == null) {
417 scrollPane = new JScrollPane(getSelectedFunctionsList(), ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
418 scrollPane.setPreferredSize(new Dimension(200,200));
419 }
420
421 return scrollPane;
422 }
423
424
425
426
427
428 public void refreshSelectedFunctionsList(){
429 getSelectedFunctionsList().repaint();
430 applyFunctionsText();
431 }
432
433
434
435
436
437
438
439
440 protected String composeFunction(Converter c, String input) {
441 return ConverterUtilities.composeFunctionString(c, input);
442 }
443
444
445
446
447
448
449 protected boolean checkEditable(Converter converter) {
450 return ConverterUtilities.isEditable(converter);
451 }
452
453
454
455
456
457
458
459 protected boolean edit(Converter converter) {
460 return ConverterUtilities.showEditorDialog(this, converter);
461 }
462
463 public static void main(String[] args) {
464 JFrame f = new JFrame("ConverterCustomizer");
465 f.add(new ConverterCustomizer());
466 f.pack();
467 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
468 f.setVisible(true);
469 }
470 }