1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.gui;
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.Image;
27 import java.awt.Insets;
28 import java.awt.event.ActionEvent;
29 import java.awt.event.ActionListener;
30 import java.awt.image.BufferedImage;
31 import java.beans.Customizer;
32 import java.beans.PropertyChangeEvent;
33 import java.beans.PropertyChangeListener;
34 import java.util.ArrayList;
35
36 import javax.swing.DefaultListCellRenderer;
37 import javax.swing.DefaultListModel;
38 import javax.swing.ImageIcon;
39 import javax.swing.JButton;
40 import javax.swing.JLabel;
41 import javax.swing.JList;
42 import javax.swing.JPanel;
43 import javax.swing.JScrollPane;
44 import javax.swing.ListCellRenderer;
45
46 import com.cosylab.gui.components.NumberField;
47 import com.cosylab.gui.components.util.RunnerHelper;
48
49
50
51
52
53
54
55
56
57 public class IconCustomizer extends JPanel implements Customizer {
58
59 private static final long serialVersionUID = -5846378735807305307L;
60
61 private class ValueHolder {
62 private ValueIconPair pair;
63 private String path;
64 public ValueHolder(ValueIconPair pair, String path) {
65 this.pair = pair;
66 this.path = path;
67 }
68
69 public boolean equals(Object o) {
70 if (!(o instanceof ValueHolder))
71 return false;
72 else return (((ValueHolder)o).pair.equals(pair));
73 }
74
75 }
76
77 private class CellRenderer extends DefaultListCellRenderer implements ListCellRenderer {
78
79 private static final long serialVersionUID = 1L;
80
81 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
82 Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
83 if (! (c instanceof JLabel)) return c;
84
85 if (value instanceof ValueHolder) {
86 JLabel component = (JLabel) c;
87 ValueHolder vh = (ValueHolder) value;
88 component.setToolTipText(vh.path);
89 if (vh.pair.getIcon() instanceof ImageIcon)
90 if (vh.pair.getIcon().getIconHeight() > 16 || vh.pair.getIcon().getIconWidth() > 16)
91 component.setIcon(getScaledIcon((ImageIcon)vh.pair.getIcon(), 16, 16));
92 else
93 component.setIcon(vh.pair.getIcon());
94 component.setText(" Value: " + vh.pair.getValue() + "; Icon: " + vh.path);
95 }
96 return c;
97 }
98
99 }
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178 private IconDisplayer displayer;
179 private NumberField numberField;
180
181 private IconEditor iconField;
182 private JList valueList;
183 private JScrollPane listScroll;
184 private JButton addButton;
185 private JButton removeButton;
186 private JPanel buttonPanel;
187
188 private JLabel valueLabel;
189 private JLabel iconLabel;
190 private DefaultListModel model;
191 private ArrayList<ValueHolder> icons = new ArrayList<ValueHolder>();
192 private IconEditor defaultIconPanel;
193 private boolean defaultIconMode = true;
194 private boolean valueIconMode = true;
195
196 private String defaultIconPath;
197
198
199
200
201
202
203 public IconCustomizer() {
204 super();
205 initialize();
206 }
207
208 private void initialize() {
209 this.setLayout(new GridBagLayout());
210 valueLabel = new JLabel("Value");
211 valueLabel.setMinimumSize(new Dimension(50,21));
212 valueLabel.setMaximumSize(new Dimension(50,21));
213 valueLabel.setPreferredSize(new Dimension(50,21));
214 valueLabel.setVisible(valueIconMode);
215 this.add(valueLabel, new GridBagConstraints(0,0,1,1,0,0,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(11,11,1,1),0,0));
216 this.add(getNumberField(), new GridBagConstraints(1,0,2,1,1,0,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(11,1,1,11),0,0));
217
218 iconLabel = new JLabel("Icon");
219 iconLabel.setMinimumSize(new Dimension(50,21));
220 iconLabel.setMaximumSize(new Dimension(50,21));
221 iconLabel.setPreferredSize(new Dimension(50,21));
222 iconLabel.setVisible(valueIconMode);
223 this.add(iconLabel, new GridBagConstraints(0,1,1,1,0,0,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(1,11,1,1),0,0));
224 this.add(getIconField(), new GridBagConstraints(1,1,1,1,1,0,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(-10,-10,-5,0),0,0));
225
226 this.add(getButtonPanel(), new GridBagConstraints(0,2,3,1,1,0,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(5,11,5,11),0,0));
227 this.add(getListScroll(), new GridBagConstraints(0,3,3,1,1,1,GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0,11,5,11),0,0));
228 this.add(getDefaultIconPanel(), new GridBagConstraints(0,4,3,1,1,0,GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(-6,0,0,0),0,0));
229 }
230
231 private IconEditor getDefaultIconPanel() {
232 if (defaultIconPanel == null) {
233 defaultIconPanel = new IconEditor("Default icon");
234 defaultIconPanel.addPropertyChangeListener(IconEditor.ICON, new PropertyChangeListener() {
235 public void propertyChange(PropertyChangeEvent evt) {
236
237 setDefaultIcon(defaultIconPanel.getIconPath());
238 }
239 });
240 }
241
242 return defaultIconPanel;
243 }
244
245 private JPanel getButtonPanel() {
246 if(buttonPanel == null) {
247 buttonPanel = new JPanel(new GridBagLayout());
248 buttonPanel.add(getAddButton(), new GridBagConstraints(0,0,1,1,1,1,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0,0,0,5),0,0));
249 buttonPanel.add(getRemoveButton(), new GridBagConstraints(1,0,1,1,1,1,GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0,5,0,0),0,0));
250 buttonPanel.setVisible(valueIconMode);
251 }
252 return buttonPanel;
253 }
254
255 private void createAndAddIcon() {
256
257 String path = getIconField().getIconPath();
258 long value = getNumberField().getLongValue();
259 ValueHolder vh = new ValueHolder(new ValueIconPair(value, path), path);
260 addIcon(vh);
261 }
262
263 private void addIcon(ValueHolder vh) {
264 getListModel().addElement(vh);
265 if (displayer != null) {
266 displayer.addIcon(vh.pair);
267 }
268
269 firePropertyChange(IconDisplayer.ICONS_PROPERTY,null,getIcons());
270 }
271
272 private void removeIcon(ValueHolder agp) {
273 if (agp == null || !icons.contains(agp)) return;
274 getListModel().removeElement(agp);
275 icons.remove(agp);
276 if (displayer != null) {
277 displayer.removeIcon(agp.pair);
278 }
279 firePropertyChange(IconDisplayer.ICONS_PROPERTY,null,getIcons());
280 }
281
282 private JButton getAddButton() {
283 if (addButton == null) {
284 addButton = new JButton("Add");
285 addButton.addActionListener(new ActionListener() {
286 public void actionPerformed(ActionEvent e) {
287 createAndAddIcon();
288 }
289 });
290 addButton.setEnabled(false);
291 }
292 return addButton;
293 }
294
295 private JButton getRemoveButton() {
296 if (removeButton == null) {
297 removeButton = new JButton("Remove");
298 removeButton.addActionListener(new ActionListener() {
299 public void actionPerformed(ActionEvent e) {
300 Object[] selected = getValueList().getSelectedValues();
301 if (selected != null) {
302 for (Object o : selected) {
303 removeIcon((ValueHolder) o);
304 }
305 }
306 }
307 });
308 }
309 return removeButton;
310 }
311
312 private NumberField getNumberField() {
313 if (numberField == null) {
314 numberField = new NumberField();
315 numberField.setNumberType(Long.class);
316 numberField.setVisible(valueIconMode);
317 }
318 return numberField;
319 }
320
321 private IconEditor getIconField() {
322 if (iconField == null) {
323 iconField = new IconEditor(null);
324 iconField.setVisible(valueIconMode);
325 iconField.addPropertyChangeListener(IconEditor.ICON, new PropertyChangeListener() {
326 public void propertyChange(PropertyChangeEvent evt) {
327 if (evt.getNewValue() != null)
328 getAddButton().setEnabled(true);
329 else
330 getAddButton().setEnabled(false);
331 }
332 });
333 }
334 return iconField;
335 }
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353 private JScrollPane getListScroll() {
354 if (listScroll == null) {
355 listScroll = new JScrollPane(getValueList());
356 listScroll.setVisible(valueIconMode);
357 listScroll.setMaximumSize(new Dimension(250, 190));
358 listScroll.setMinimumSize(new Dimension(250, 190));
359 listScroll.setPreferredSize(new Dimension(250, 190));
360 }
361 return listScroll;
362 }
363
364 private JList getValueList() {
365 if (valueList == null) {
366 valueList = new JList();
367 valueList.setCellRenderer(new CellRenderer());
368 valueList.setModel(getListModel());
369 }
370 return valueList;
371 }
372
373 private DefaultListModel getListModel() {
374 if (model == null) {
375 model = new DefaultListModel() {
376 private static final long serialVersionUID = -3602336759931247665L;
377
378 @Override
379 public void addElement(Object o) {
380 long value = ((ValueHolder)o).pair.getValue();
381 ValueHolder old;
382 if (getSize() != 0) {
383 for (int i = 0; i < getSize(); i++) {
384 old = (ValueHolder) getElementAt(i);
385 if (value < old.pair.getValue()) {
386 super.add(i, o);
387 return;
388 } else if (value == old.pair.getValue()) {
389 super.add(i, o);
390 removeElement(old);
391 return;
392 }
393
394 }
395 super.addElement(o);
396 } else {
397 super.add(0, o);
398 }
399
400
401
402 }
403 };
404 }
405 return model;
406 }
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445 public void setDefaultIcon(String icon) {
446 String old = this.defaultIconPath;
447 if ((old != null && old.equals(icon)) || (old == null && icon == null)) return;
448
449 this.defaultIconPath = icon;
450 getDefaultIconPanel().setIcon(icon);
451 if (displayer != null)
452 displayer.setDefaultIconName(icon);
453 firePropertyChange(IconDisplayer.DEFAULT_ICON_NAME_PROPERTY, old, defaultIconPath);
454 }
455
456
457
458
459
460
461 public String getDefaultIcon() {
462 return defaultIconPath;
463 }
464
465
466
467
468
469 public void setObject(Object bean) {
470 if (!(bean instanceof IconDisplayer)) return;
471 this.displayer = (IconDisplayer) bean;
472 this.displayer.addPropertyChangeListener(IconDisplayer.ICONS_PROPERTY, new PropertyChangeListener() {
473 public void propertyChange(PropertyChangeEvent evt) {
474 if (!IconDisplayer.ICONS_PROPERTY.equals(evt.getPropertyName())) return;
475 setIcons(displayer.getIcons());
476 }
477 });
478 this.displayer.addPropertyChangeListener(IconDisplayer.DEFAULT_ICON_NAME_PROPERTY, new PropertyChangeListener() {
479 public void propertyChange(PropertyChangeEvent evt) {
480 if (!IconDisplayer.DEFAULT_ICON_NAME_PROPERTY.equals(evt.getPropertyName())) return;
481
482 setDefaultIcon(displayer.getDefaultIconName());
483 }
484 });
485 setDefaultIcon(displayer.getDefaultIconName());
486 setIcons(displayer.getIcons());
487 }
488
489
490
491
492
493
494 public void setIcons(ValueIconPair[] pairs) {
495 if (pairs == null) return;
496
497 ArrayList<ValueHolder> toBeRemoved = new ArrayList<ValueHolder>();
498
499 if (icons != null) {
500 for(ValueHolder cp : icons) {
501 toBeRemoved.add(cp);
502 }
503 } else {
504 icons = new ArrayList<ValueHolder>();
505 }
506
507 ArrayList<ValueHolder> toBeAdded = new ArrayList<ValueHolder>();
508
509
510 ValueHolder vh;
511 for (ValueIconPair pair : pairs) {
512 vh = new ValueHolder(pair, pair.getIconName());
513 if (toBeRemoved.contains(vh)) {
514 toBeRemoved.remove(vh);
515 } else {
516 toBeAdded.add(vh);
517 }
518 }
519
520 for (ValueHolder p : toBeRemoved) {
521 getListModel().removeElement(p);
522 icons.remove(p);
523 }
524
525 for (ValueHolder p : toBeAdded) {
526 getListModel().addElement(p);
527 icons.add(p);
528 }
529
530 firePropertyChange(IconDisplayer.ICONS_PROPERTY,null,getIcons());
531
532 }
533
534
535
536
537
538
539 public ValueIconPair[] getIcons() {
540 ValueIconPair[] icons = new ValueIconPair[getListModel().size()];
541 for (int i = 0; i< getListModel().size(); i++) {
542 icons[i] = ((ValueHolder) getListModel().get(i)).pair;
543 }
544 return icons;
545 }
546
547
548
549
550
551
552
553 public void setDefaultIconMode(boolean defaultIconMode) {
554 if (this.defaultIconMode == defaultIconMode) return;
555 this.defaultIconMode = defaultIconMode;
556 getDefaultIconPanel().setVisible(this.defaultIconMode);
557 }
558
559
560
561
562
563
564
565 public void setValueIconMode(boolean valueIconMode) {
566 if (this.valueIconMode == valueIconMode) return;
567 this.valueIconMode = valueIconMode;
568 iconLabel.setVisible(this.valueIconMode);
569 valueLabel.setVisible(this.valueIconMode);
570 getNumberField().setVisible(this.valueIconMode);
571 getIconField().setVisible(this.valueIconMode);
572
573 getButtonPanel().setVisible(this.valueIconMode);
574 getListScroll().setVisible(this.valueIconMode);
575 }
576
577
578
579
580
581
582 public boolean getValueIconMode() {
583 return valueIconMode;
584 }
585
586
587
588
589
590
591 public boolean getDefaultIconMode() {
592 return defaultIconMode;
593 }
594
595
596
597
598
599
600
601
602
603 public static ImageIcon getScaledIcon(ImageIcon icon, int maxHeight, int maxWidth) {
604
605 int height = icon.getIconHeight();
606 int width = icon.getIconWidth();
607 double aspect = (double)height/width;
608
609 width = (int)(maxHeight/aspect);
610 if (width > maxWidth) {
611 height =(int) (maxWidth*aspect);
612 width = maxWidth;
613 } else{
614 height = maxHeight;
615 }
616
617 return new ImageIcon(icon.getImage().getScaledInstance(
618 width, height, Image.SCALE_FAST));
619 }
620
621
622
623
624
625
626
627
628
629 public static ImageIcon getScaledImage(BufferedImage image, int maxHeight, int maxWidth) {
630
631 int height = image.getHeight();
632 int width = image.getWidth();
633 double aspect = (double)height/width;
634
635 width = (int)(maxHeight/aspect);
636 if (width > maxWidth) {
637 height =(int) (maxWidth*aspect);
638 width = maxWidth;
639 } else{
640 height = maxHeight;
641 }
642
643 return new ImageIcon(image.getScaledInstance(
644 width, height, Image.SCALE_DEFAULT));
645 }
646
647 public static void main(String[] args) {
648 IconCustomizer c = new IconCustomizer();
649 c.setDefaultIconMode(true);
650 c.setValueIconMode(false);
651 RunnerHelper.runComponent(c, 500, 400);
652
653
654
655
656
657
658 }
659
660 }