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;
21
22 import java.awt.Color;
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.ComponentAdapter;
29 import java.awt.event.ComponentEvent;
30 import java.awt.event.ComponentListener;
31 import java.beans.Beans;
32
33 import javax.swing.AbstractAction;
34 import javax.swing.JComponent;
35 import javax.swing.JLabel;
36 import javax.swing.JPanel;
37 import javax.swing.TransferHandler;
38
39 import com.cosylab.application.state.State;
40 import com.cosylab.application.state.StateFactory;
41 import com.cosylab.application.state.StateOriginator;
42 import com.cosylab.gui.components.customizer.AbstractCustomizerPanel;
43 import com.cosylab.gui.components.util.ColorHelper;
44 import com.cosylab.gui.components.util.CosyTransferHandler;
45 import com.cosylab.gui.components.util.CosyUIElements;
46 import com.cosylab.gui.components.util.PopupManageable;
47 import com.cosylab.gui.components.util.PopupManager;
48 import com.cosylab.gui.components.util.ScreenCapturer;
49
50
51
52
53
54
55
56
57
58
59
60
61 public abstract class AbstractDisplayerPanel extends JPanel
62 implements PopupManageable, StateOriginator
63 {
64 private static final long serialVersionUID = 1L;
65
66
67 public static final int HORIZONTAL_LAYOUT = 0;
68
69
70 public static final int VERTICAL_LAYOUT = 1;
71
72
73
74
75
76
77 public static final int DYNAMIC_LAYOUT = 2;
78 private ComponentListener resizeListener;
79 private AbstractCustomizerPanel customizer;
80 private PopupManager popupManager;
81 private boolean popupEnabled;
82 private ResizableTextLabel titleLabel;
83 private String title;
84 private boolean enhanced;
85 private boolean resizable;
86 private int minTitleFontSize = 0;
87 private int maxTitleFontSize = Integer.MAX_VALUE;
88 private boolean titleVisible;
89 private int layoutOrientation = DYNAMIC_LAYOUT;
90
91
92
93
94
95 public AbstractDisplayerPanel()
96 {
97 this(null, false, DYNAMIC_LAYOUT, true, true, true, 1, Integer.MAX_VALUE);
98 }
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 public AbstractDisplayerPanel(String title, boolean titleVisible,
115 int layoutOrientation, boolean resizable, boolean enabled,
116 boolean enchanced, int minTitleFontSize, int maxTitleFontSize)
117 {
118 super();
119
120 setBackground(ColorHelper.getCosyControl());
121 setBorder(new CosyUIElements.PanelFlushBorder());
122 setPreferredSize(new Dimension(200, 50));
123 setMinimumSize(new Dimension(200, 50));
124 setLayout(new GridBagLayout());
125
126
127 addComponentListener(new ComponentAdapter() {
128 public void componentResized(ComponentEvent e)
129 {
130 layoutDisplayer();
131 }
132 });
133
134
135 setTitle(title);
136 setTitleVisible(titleVisible);
137 setLayoutOrientation(layoutOrientation);
138 setResizable(resizable);
139 setEnabled(enabled);
140 setEnhanced(enchanced);
141 setTitleMinimumFontSize(minTitleFontSize);
142 setTitleMaximumFontSize(maxTitleFontSize);
143 setPopupEnabled(true);
144 }
145
146
147
148
149
150
151
152
153 public AbstractCustomizerPanel getCustomizer()
154 {
155 if (customizer == null) {
156 customizer = AbstractCustomizerPanel.findCustomizer(this);
157 }
158
159 return customizer;
160 }
161
162
163
164
165
166
167 public void setEnabled(boolean enabled)
168 {
169 if (enabled == isEnabled()) {
170 return;
171 }
172
173 super.setEnabled(enabled);
174 internalSetEnabled();
175 }
176
177
178
179
180
181
182 public void setEnhanced(boolean b)
183 {
184 if (enhanced == b) {
185 return;
186 }
187
188 enhanced = b;
189 internalSetEnhanced();
190 firePropertyChange("enhanced", !b, b);
191 }
192
193
194
195
196
197
198 public boolean isEnhanced()
199 {
200 return enhanced;
201 }
202
203
204
205
206
207
208
209
210
211
212
213
214 public void setLayoutOrientation(int i)
215 {
216 if (i == layoutOrientation) {
217 return;
218 }
219
220 if (i != HORIZONTAL_LAYOUT && i != VERTICAL_LAYOUT
221 && i != DYNAMIC_LAYOUT) {
222 throw new IllegalArgumentException();
223 }
224
225 int oldVal = layoutOrientation;
226
227 layoutOrientation = i;
228
229 if (i == DYNAMIC_LAYOUT) {
230 addComponentListener(getResizeListener());
231 } else if (oldVal == DYNAMIC_LAYOUT) {
232 removeComponentListener(getResizeListener());
233 }
234
235 layoutDisplayer();
236 firePropertyChange("layoutOrientation", oldVal, i);
237 }
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266 public int getLayoutOrientation()
267 {
268 return layoutOrientation;
269 }
270
271
272
273
274
275
276 public PopupManager getPopupManager()
277 {
278 if (popupManager == null) {
279 popupManager = new PopupManager(this, false);
280 popupManager.addAction(new AbstractAction("Preferences...") {
281 private static final long serialVersionUID = 1L;
282 public void actionPerformed(ActionEvent e)
283 {
284 getCustomizer().showDialog();
285 }
286 });
287 popupManager.addAction(new AbstractAction("Capture screen..."){
288 private static final long serialVersionUID = 1L;
289
290 public void actionPerformed(ActionEvent e){
291 ScreenCapturer sc = new ScreenCapturer(AbstractDisplayerPanel.this);
292 sc.showScreenDialog();
293 }
294 });
295 }
296
297 return popupManager;
298 }
299
300
301
302
303
304
305 public boolean isPopupEnabled() {
306 return popupEnabled;
307 }
308
309
310
311
312
313
314 public void setPopupEnabled(boolean enabled) {
315 if (popupEnabled == enabled) return;
316 popupEnabled = enabled;
317 if (enabled) {
318 getValueComponent().addMouseListener(getPopupManager().getMouseHook());
319 addMouseListener(getPopupManager().getMouseHook());
320 getTitleComponent().addMouseListener(getPopupManager().getMouseHook());
321 } else {
322 getValueComponent().removeMouseListener(getPopupManager().getMouseHook());
323 removeMouseListener(getPopupManager().getMouseHook());
324 getTitleComponent().removeMouseListener(getPopupManager().getMouseHook());
325 }
326 firePropertyChange("popupEnabled",!popupEnabled,popupEnabled);
327 }
328
329
330
331
332
333
334
335
336
337 public void setResizable(boolean b)
338 {
339 if (resizable == b) {
340 return;
341 }
342
343 resizable = b;
344 internalSetResizable();
345 layoutDisplayer();
346 firePropertyChange("resizable", !b, b);
347 }
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364 public boolean isResizable()
365 {
366 return resizable;
367 }
368
369
370
371
372
373
374
375
376 public void setState(State state)
377 {
378 setTitle(state.getString("title", getTitle()));
379 setResizable(state.getBoolean("resizable", isResizable()));
380 setTitleVisible(state.getBoolean("titleVisible", isTitleVisible()));
381 setLayoutOrientation(state.getInt("layoutOrientation",
382 getLayoutOrientation()));
383 }
384
385
386
387
388
389
390
391
392 public State getState()
393 {
394 State state = StateFactory.createState();
395
396 state.putBoolean("resizable", isResizable());
397 state.putString("title", getTitle());
398 state.putBoolean("titleVisible", isTitleVisible());
399 state.putInt("layoutOrientation", getLayoutOrientation());
400
401 return state;
402 }
403
404
405
406
407
408
409 public void setTitle(String value)
410 {
411 String oldVal = title;
412 title = value;
413 internalSetTitle();
414 layoutDisplayer();
415 firePropertyChange("title", oldVal, value);
416 }
417
418
419
420
421
422
423 public String getTitle()
424 {
425 return title;
426 }
427
428
429
430
431
432
433 public void setTitleVisible(boolean b)
434 {
435 if (b == titleVisible) {
436 return;
437 }
438
439 titleVisible = b;
440 layoutDisplayer();
441 firePropertyChange("titleVisible", !b, b);
442 }
443
444
445
446
447
448
449
450
451 public boolean isTitleVisible()
452 {
453 return titleVisible;
454 }
455
456 private ComponentListener getResizeListener()
457 {
458 if (resizeListener == null) {
459 resizeListener = new ComponentAdapter() {
460 public void componentResized(ComponentEvent e)
461 {
462 layoutDisplayer();
463 }
464 };
465 }
466
467 return resizeListener;
468 }
469
470
471
472
473
474
475
476 protected JLabel getTitleComponent()
477 {
478 if (titleLabel == null) {
479 titleLabel = new ResizableTextLabel();
480 titleLabel.setHorizontalAlignment(JLabel.CENTER);
481 titleLabel.setEnabled(isEnabled());
482 titleLabel.setEnhanced(isEnhanced());
483 titleLabel.setResizable(isResizable());
484 titleLabel.setMaximumFontSize(maxTitleFontSize);
485 titleLabel.setMinimumFontSize(minTitleFontSize);
486 internalSetTitle();
487 }
488
489 return titleLabel;
490 }
491
492
493
494
495
496
497
498
499
500 protected abstract JComponent getValueComponent();
501
502 protected void internalSetEnabled()
503 {
504 if (titleLabel != null) {
505 titleLabel.setEnabled(isEnabled());
506 }
507 }
508
509 protected void internalSetEnhanced()
510 {
511 if (titleLabel != null) {
512 titleLabel.setEnhanced(isEnhanced());
513 }
514 }
515
516 protected void internalSetResizable()
517 {
518 if (titleLabel != null) {
519 titleLabel.setResizable(isResizable());
520 }
521 }
522
523 protected void internalSetTitle()
524 {
525 if (titleLabel == null) {
526 return;
527 }
528
529 String value = title;
530
531 if (value == null && Beans.isDesignTime()) {
532 value = "<title>";
533 }
534
535
536
537
538 titleLabel.setText(value);
539 }
540
541
542
543
544 protected void layoutDisplayer()
545 {
546 if (isTitleVisible() && getTitle() != null && getTitle().length() > 0) {
547
548 layoutValueAndTitle();
549
550 } else {
551
552 layoutValue();
553
554 }
555 }
556
557 protected void layoutValue()
558 {
559 removeAll();
560 Insets insets = new Insets(getSize().height * 3 / 100,
561 getSize().width * 3 / 100, getSize().height * 3 / 100,
562 getSize().width * 3 / 100);
563 int fill = (isResizable() ? GridBagConstraints.BOTH
564 : GridBagConstraints.NONE);
565
566 add(getValueComponent(),
567 new GridBagConstraints(1, 1, 1, 1, 1, 1, GridBagConstraints.CENTER,
568 fill, insets, 0, 0));
569 }
570
571 protected void layoutValueAndTitle()
572 {
573 removeAll();
574
575 Insets insets = !isResizable() ? new Insets(2, 2, 2, 2)
576 : new Insets(getSize().height * 3 / 100, getSize().width * 3 / 100,
577 getSize().height * 3 / 100, getSize().width * 3 / 100);
578
579
580 int fill = (isResizable() ? GridBagConstraints.BOTH
581 : GridBagConstraints.NONE);
582 double w = isResizable() ? 1.0 : 0.0;
583
584
585 if (1. * (getSize().height) / (getTitleComponent().getPreferredSize().height
586 + getValueComponent().getPreferredSize().height) > 1. * (getSize().width) / (getTitleComponent()
587 .getPreferredSize().width
588 + getValueComponent().getPreferredSize().width)
589 && getLayoutOrientation() == AbstractDisplayerPanel.DYNAMIC_LAYOUT
590 || getLayoutOrientation() == AbstractDisplayerPanel.VERTICAL_LAYOUT) {
591 add(getTitleComponent(),
592 new GridBagConstraints(1, 1, 1, 1, w, w,
593 GridBagConstraints.CENTER, fill, insets, 0, 0));
594 add(getValueComponent(),
595 new GridBagConstraints(1, 2, 1, 1, w, w * 1.2,
596 GridBagConstraints.CENTER, fill, insets, 0, 0));
597 } else {
598 add(getTitleComponent(),
599 new GridBagConstraints(1, 1, 1, 1, w, w,
600 GridBagConstraints.EAST, fill, insets, 0, 0));
601 add(getValueComponent(),
602 new GridBagConstraints(2, 1, 1, 1, w * 1.2, w,
603 GridBagConstraints.WEST, fill, insets, 0, 0));
604 }
605 }
606
607
608
609
610
611
612 public int getTitleMaximumFontSize()
613 {
614 return maxTitleFontSize;
615 }
616
617
618
619
620
621
622 public int getTitleMinimumFontSize()
623 {
624 return minTitleFontSize;
625 }
626
627
628
629
630
631
632 public void setTitleMaximumFontSize(int max)
633 {
634 if (max == maxTitleFontSize) {
635 return;
636 }
637
638 int oldValue = maxTitleFontSize;
639 maxTitleFontSize = max;
640 layoutDisplayer();
641 if (titleLabel!=null) titleLabel.setMaximumFontSize(maxTitleFontSize);
642 firePropertyChange(AbstractDisplayerPanelCustomizer.MAX_TITLE_FONT_SIZE,
643 oldValue, max);
644 }
645
646
647
648
649
650
651 public void setTitleMinimumFontSize(int min)
652 {
653 if (min == minTitleFontSize) {
654 return;
655 }
656
657 int oldValue = minTitleFontSize;
658 minTitleFontSize = min;
659 layoutDisplayer();
660 if (titleLabel!=null) titleLabel.setMinimumFontSize(minTitleFontSize);
661 firePropertyChange(AbstractDisplayerPanelCustomizer.MIN_TITLE_FONT_SIZE,
662 oldValue, min);
663 }
664
665
666
667
668 @Override
669 public void setTransferHandler(TransferHandler newHandler) {
670 super.setTransferHandler(newHandler);
671 CosyTransferHandler.registerTransferHandler(this,newHandler,new JComponent[]{getTitleComponent()});
672 }
673
674
675
676
677
678
679
680 public void setDragEnabled(boolean enabled) {
681 if (isDragEnabled() == enabled) return;
682 if (getTransferHandler() instanceof CosyTransferHandler) {
683 if (((CosyTransferHandler)getTransferHandler()).isExportEnabled() == enabled) return;
684
685 ((CosyTransferHandler)getTransferHandler()).setExportEnabled(enabled, this);
686 }
687 firePropertyChange("dragEnabled", !enabled, enabled);
688 }
689
690
691
692
693
694
695 public boolean isDragEnabled() {
696 if (getTransferHandler() instanceof CosyTransferHandler) {
697 return ((CosyTransferHandler)getTransferHandler()).isExportEnabled();
698 } else {
699 return getTransferHandler() != null;
700 }
701 }
702
703
704
705
706
707
708
709 public void setDropEnabled(boolean enabled) {
710 if (isDropEnabled() == enabled) return;
711 if (getTransferHandler() instanceof CosyTransferHandler) {
712 if (((CosyTransferHandler)getTransferHandler()).isReceiveEnabled() == enabled) return;
713
714 ((CosyTransferHandler)getTransferHandler()).setReceiveEnabled(enabled, this);
715 }
716
717 firePropertyChange("dropEnabled", !enabled, enabled);
718 }
719
720
721
722
723
724
725 public boolean isDropEnabled() {
726 if (getTransferHandler() instanceof CosyTransferHandler) {
727 return ((CosyTransferHandler)getTransferHandler()).isReceiveEnabled();
728 } else {
729 return getTransferHandler() != null;
730 }
731 }
732
733
734
735
736
737 @Override
738 public void setBackground(Color bg) {
739 super.setBackground(bg);
740 getValueComponent().setBackground(bg);
741 getTitleComponent().setBackground(bg);
742 }
743
744
745
746
747
748 @Override
749 public void setForeground(Color fg) {
750 super.setForeground(fg);
751 getValueComponent().setForeground(fg);
752 getTitleComponent().setForeground(fg);
753 }
754
755
756 }
757
758