1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.cosylab.gui.plugins;
21
22 import java.awt.AWTEvent;
23 import java.awt.Component;
24 import java.awt.Container;
25 import java.awt.Graphics;
26 import java.awt.Point;
27 import java.awt.Rectangle;
28 import java.awt.Toolkit;
29 import java.awt.event.AWTEventListener;
30 import java.awt.event.ComponentEvent;
31 import java.awt.event.ComponentListener;
32 import java.awt.event.MouseEvent;
33 import java.beans.PropertyChangeEvent;
34 import java.beans.PropertyChangeListener;
35 import java.util.ArrayList;
36 import java.util.Date;
37 import java.util.List;
38 import java.util.logging.Level;
39 import java.util.logging.Logger;
40
41 import javax.swing.JComponent;
42 import javax.swing.JRootPane;
43 import javax.swing.SwingUtilities;
44
45 import com.cosylab.application.PlugIn;
46 import com.cosylab.application.PlugInException;
47 import com.cosylab.application.PlugInManager;
48 import com.cosylab.gui.components.util.ColorHelper;
49 import com.cosylab.gui.components.util.PaintHelper;
50 import com.cosylab.gui.displayers.DataState;
51 import com.cosylab.gui.displayers.DataStateProvider;
52 import com.cosylab.logging.DebugLogger;
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 public class VitragePlugIn extends JComponent implements PlugIn,
68 PropertyChangeListener, ComponentListener
69 {
70
71 private static final long serialVersionUID = 1L;
72
73
74
75
76
77 public final static String ENHANCED = "vitrageplugin.antialiasing";
78 private final static Logger logger = DebugLogger.getLogger("VP", Level.OFF);
79
80
81 private Container contentPane = null;
82 private List<DataStateProvider> displayers = null;
83 private boolean isEnabled;
84 private boolean isInHierarchy;
85
86
87
88
89 public VitragePlugIn()
90 {
91 super();
92 setOpaque(false);
93 displayers = new ArrayList<DataStateProvider>();
94 }
95
96
97
98
99
100
101
102
103 public VitragePlugIn(JComponent comp)
104 {
105 this();
106 installToRoot(comp.getRootPane());
107
108 hookAWT(comp);
109 }
110
111 private void hookAWT(Container comp)
112 {
113 Component[] components = comp.getComponents();
114
115 if (components == null) {
116 return;
117 }
118
119 for (int i = 0; i < components.length; i++) {
120 if (components[i] instanceof DataStateProvider) {
121 hookDisplayer((DataStateProvider)components[i]);
122 }
123
124 if (components[i] instanceof Container) {
125 hookAWT((Container)components[i]);
126 }
127 }
128 }
129
130
131
132
133
134 public void installPlugIn(PlugInManager manager) throws PlugInException
135 {
136 if (manager == null) {
137 throw new NullPointerException("manager");
138 }
139
140 logger.info("Installing to " + manager);
141
142
143
144
145
146
147 JRootPane root = SwingUtilities.getRootPane(manager.getOwnerPanel().getContentPane());
148
149 if (root != null) {
150 installToRoot(root);
151 }
152
153 }
154
155 private void installToRoot(JRootPane root)
156 {
157 contentPane = root.getContentPane();
158
159 if (!isInHierarchy) {
160 if (root != null) {
161 root.getLayeredPane().add(this, new Integer(1), -1);
162 setLocation(SwingUtilities.convertPoint(contentPane, 0, 0,
163 getParent()));
164 setSize(contentPane.getSize());
165 root.addComponentListener(this);
166 isInHierarchy = true;
167 root.getLayeredPane().validate();
168
169
170
171 try {
172 Toolkit.getDefaultToolkit().addAWTEventListener(new CursorListener(
173 contentPane), AWTEvent.MOUSE_EVENT_MASK);
174 } catch (SecurityException e) {
175 System.out.println(
176 "No permission to access AWT, Vitrage my not function property: "
177 + e.getMessage());
178 }
179 }
180 }
181 }
182
183 private void hookDisplayer(DataStateProvider disp)
184 {
185 logger.fine("disp " + disp);
186 disp.addPropertyChangeListener(this);
187
188 if (disp.getDataState().type != DataState.NORMAL
189 && disp.getDataState().type != DataState.CONNECTED) {
190 addPaintedDisplayer(disp);
191 }
192 }
193
194 @SuppressWarnings("unused")
195 private void unhookDisplayer(DataStateProvider disp)
196 {
197 logger.fine("disp " + disp);
198 disp.removePropertyChangeListener(this);
199 removePaintedDisplayer(disp);
200 }
201
202
203
204
205
206 public void displayerStateChanged(DataStateProvider source)
207 {
208 if (source.getDataState().type == DataState.NORMAL
209
210 ) {
211 removePaintedDisplayer(source);
212 } else {
213 addPaintedDisplayer(source);
214 }
215 }
216
217
218
219
220
221 public void destroy()
222 {
223 }
224
225
226
227
228
229
230
231
232 public void paintComponent(Graphics g)
233 {
234 super.paintComponent(g);
235
236 if (isEnabled) {
237 logger.fine("Painting");
238
239 DataStateProvider displayer = null;
240 Component component = null;
241 long timeoutTime;
242 String state;
243 Rectangle r;
244
245 for (int i = 0; i < displayers.size(); i++) {
246 displayer = (DataStateProvider)displayers.get(i);
247 component = (Component)displayer;
248
249 if (!component.isShowing()) {
250 continue;
251 }
252
253 if (!component.isDisplayable()) {
254 continue;
255 }
256
257 r = SwingUtilities.convertRectangle(component.getParent(),
258 component.getBounds(), this);
259
260
261
262
263
264
265 state = displayer.getDataState().type;
266 timeoutTime = displayer.getDataState().timestamp;
267
268 if (state == DataState.NOT_INITIALIZED
269 || state == DataState.DISCONNECTED
270 || state == DataState.UNDEFINED) {
271 logger.fine("Painting DISABLED " + displayer);
272 PaintHelper.paintDisabled(g.create(r.x, r.y, r.width,
273 r.height), 0, 0, r.width, r.height);
274 } else {
275 int timeSize = (int)(Math.min(r.width, r.height) * 8.8 / 10);
276 int stateSize = (int)(Math.min(r.width, r.height) * 9. / 10);
277
278 if (stateSize < 1) {
279 stateSize = 1;
280 }
281
282 if (timeSize < 1) {
283 timeSize = 1;
284 }
285
286 int timeX = (r.width - timeSize) / 2;
287 int timeY = (r.height - timeSize) / 2;
288 int stateX = (r.width - stateSize) / 2;
289 int stateY = (r.height - stateSize) / 2;
290
291 if (state == DataState.WARNING) {
292 logger.fine("Painting WARNING " + displayer);
293 PaintHelper.paintWarning(g.create(r.x, r.y, r.width,
294 r.height), stateX, stateY, stateSize);
295 } else if (state == DataState.ALARM) {
296 String severity= displayer.getDataState().description;
297 logger.fine("Painting ALARM " + displayer+ " "+severity);
298 if ("INVALID_ALARM".equals(severity)) {
299 PaintHelper.paintAlarmInvalid(g.create(r.x, r.y, r.width,
300 r.height), stateX, stateY, stateSize);
301 } else if ("MAJOR_ALARM".equals(severity)) {
302 PaintHelper.paintAlarmMajor(g.create(r.x, r.y, r.width,
303 r.height), stateX, stateY, stateSize);
304 } else if ("MINOR_ALARM".equals(severity)) {
305 PaintHelper.paintAlarmMinor(g.create(r.x, r.y, r.width,
306 r.height), stateX, stateY, stateSize);
307 }
308 } else if (state == DataState.ERROR) {
309 logger.fine("Painting ERROR " + displayer);
310 PaintHelper.paintEmergency(g.create(r.x, r.y, r.width,
311 r.height), stateX, stateY, stateSize);
312 PaintHelper.paintRectangle(g.create(r.x, r.y, r.width,
313 r.height), 0, 0, r.width, r.height,
314 ColorHelper.getEmergencyOutline(),
315 Math.max(stateSize / 50,2));
316 } else if (state == DataState.TIMEOUT) {
317 logger.fine("Painting TIMEOUT " + displayer);
318 PaintHelper.paintTimeout(g.create(r.x, r.y, r.width,
319 r.height), timeX, timeY, timeSize,
320 new Date(timeoutTime));
321 PaintHelper.paintRectangle(g.create(r.x, r.y, r.width,
322 r.height), 0, 0, r.width, r.height,
323 ColorHelper.getTimeOutOutline(), Math.max(stateSize / 50,2));
324 }
325 }
326 }
327 }
328 }
329
330 private void addPaintedDisplayer(DataStateProvider displayer)
331 {
332 synchronized (displayers) {
333 if (!displayers.contains(displayer)) {
334 logger.fine("disp " + displayer);
335 displayers.add(displayer);
336
337 if (!isEnabled) {
338 setVitrageEnabled(true);
339 }
340 }
341 }
342
343 repaint();
344 }
345
346 private void removePaintedDisplayer(DataStateProvider displayer)
347 {
348 synchronized (displayers) {
349 if (displayers.contains(displayer)) {
350 logger.fine("disp " + displayer);
351 displayers.remove(displayer);
352
353 if (displayers.size() == 0) {
354 setVitrageEnabled(false);
355 }
356 }
357 }
358
359 repaint();
360 }
361
362
363
364
365
366
367 public void setVitrageEnabled(boolean enabled)
368 {
369 isEnabled = enabled;
370 }
371
372
373
374
375
376
377 public boolean isVitrageEnabled() {
378 return isEnabled;
379 }
380
381
382
383
384
385 public void componentHidden(ComponentEvent e)
386 {
387 isEnabled = false;
388 }
389
390
391
392
393
394 public void componentMoved(ComponentEvent e)
395 {
396 if (getParent() == null) {
397 return;
398 }
399 }
400
401
402
403
404
405 public void componentResized(ComponentEvent e)
406 {
407 setSize(contentPane.getSize());
408 }
409
410
411
412
413
414 public void componentShown(ComponentEvent e)
415 {
416 isEnabled = true;
417 }
418
419
420
421
422
423
424 public void propertyChange(PropertyChangeEvent evt)
425 {
426 if (evt.getSource() instanceof DataStateProvider
427 && ("dataState").equals(evt.getPropertyName())) {
428
429 DataState nds = (DataState)evt.getNewValue();
430 DataState ods = (DataState)evt.getOldValue();
431 if (nds == null || ods == null
432 || nds.type != ods.type
433 || nds.description!=ods.description) {
434 displayerStateChanged((DataStateProvider)evt.getSource());
435 }
436
437 }
438 }
439
440
441
442
443
444 private class CursorListener implements AWTEventListener
445 {
446 Container contentPane;
447
448
449
450
451
452
453 public CursorListener(Container contentPane)
454 {
455 this.contentPane = contentPane;
456 }
457
458
459
460
461
462 public void eventDispatched(AWTEvent event)
463 {
464 if (event instanceof MouseEvent) {
465 MouseEvent evt = (MouseEvent)event;
466 Point ePt = evt.getPoint();
467 Point pt = SwingUtilities.convertPoint(evt.getComponent(),
468 ePt.x, ePt.y, contentPane);
469 Component topC = SwingUtilities.getDeepestComponentAt(contentPane,
470 pt.x, pt.y);
471
472 if (topC != null) {
473 setCursor(topC.getCursor());
474 }
475 }
476 }
477 }
478 }
479
480