1 | /* |
---|
2 | * $Id: PanelHolder.java,v 1.4 2003/08/27 23:29:40 dwd Exp $ |
---|
3 | * |
---|
4 | * This software is provided by NOAA for full, free and open release. It is |
---|
5 | * understood by the recipient/user that NOAA assumes no liability for any |
---|
6 | * errors contained in the code. Although this software is released without |
---|
7 | * conditions or restrictions in its use, it is expected that appropriate |
---|
8 | * credit be given to its author and to the National Oceanic and Atmospheric |
---|
9 | * Administration should the software be included by the recipient as an |
---|
10 | * element in other product development. |
---|
11 | */ |
---|
12 | |
---|
13 | package gov.noaa.pmel.sgt.beans; |
---|
14 | |
---|
15 | |
---|
16 | import java.awt.Rectangle; |
---|
17 | import java.awt.Color; |
---|
18 | import javax.swing.event.*; |
---|
19 | import javax.swing.border.Border; |
---|
20 | import javax.swing.border.LineBorder; |
---|
21 | import java.util.*; |
---|
22 | import java.io.*; |
---|
23 | import java.beans.*; |
---|
24 | |
---|
25 | /** |
---|
26 | * Object to hold all the objects necessary to describe a <code>Panel</code>. |
---|
27 | * Associated objects include <code>Label</code>, <code>DataGroup</code>, and |
---|
28 | * <code>Legend</code>. |
---|
29 | * |
---|
30 | * @author Donald Denbo |
---|
31 | * @version $Revision: 1.4 $, $Date: 2003/08/27 23:29:40 $ |
---|
32 | * @since 3.0 |
---|
33 | * @see Label |
---|
34 | * @see Panel |
---|
35 | * @see PanelModel PanelModel for UML diagram |
---|
36 | * @see DataGroup |
---|
37 | * @see Legend |
---|
38 | **/ |
---|
39 | public class PanelHolder implements ChangeListener, Serializable { |
---|
40 | private String id = ""; |
---|
41 | private Rectangle bounds = new Rectangle(0, 0, 100, 50); |
---|
42 | /** @link aggregation |
---|
43 | * @supplierCardinality * |
---|
44 | * @label labels */ |
---|
45 | /*#Label lnkLabel; */ |
---|
46 | private Map labels_ = new HashMap(5); |
---|
47 | /** @link aggregation |
---|
48 | * @supplierCardinality 1..* |
---|
49 | * @label dataGroups */ |
---|
50 | /*#DataGroup lnkDataGroup; */ |
---|
51 | private Map dataGroups_ = new HashMap(2); |
---|
52 | /** @link aggregation |
---|
53 | * @supplierCardinality * |
---|
54 | * @label legends */ |
---|
55 | /*#Legend lnkLegend; */ |
---|
56 | private Map legends_ = new HashMap(1); |
---|
57 | |
---|
58 | /** |
---|
59 | * @label pModel |
---|
60 | */ |
---|
61 | transient private PanelModel pModel_ = null; |
---|
62 | transient private ChangeEvent changeEvent_ = new ChangeEvent(this); |
---|
63 | transient private Vector changeListeners; |
---|
64 | private boolean visible = true; |
---|
65 | transient private boolean instantiated = false; |
---|
66 | private Border border = new LineBorder(Color.gray, 2); |
---|
67 | private Color background = Color.white; |
---|
68 | private boolean usePageBackground = true; |
---|
69 | |
---|
70 | static { |
---|
71 | try { |
---|
72 | BeanInfo info = Introspector.getBeanInfo(PanelHolder.class); |
---|
73 | PropertyDescriptor[] descriptors = info.getPropertyDescriptors(); |
---|
74 | for(int i=0; i < descriptors.length; i++) { |
---|
75 | PropertyDescriptor pd = descriptors[i]; |
---|
76 | if(pd.getName().equals("instantiated")) { |
---|
77 | pd.setValue("transient", Boolean.TRUE); |
---|
78 | } else if(pd.getName().equals("panelModel")) { |
---|
79 | pd.setValue("transient", Boolean.TRUE); |
---|
80 | } |
---|
81 | } |
---|
82 | } catch (IntrospectionException ie) { |
---|
83 | ie.printStackTrace(); |
---|
84 | } |
---|
85 | } |
---|
86 | /** |
---|
87 | * Default constructor. Sets <code>PanelHolder</code> identifier and |
---|
88 | * <code>PanelModel</code> parent to <code>null</code>. |
---|
89 | */ |
---|
90 | public PanelHolder() { |
---|
91 | this(null, null); |
---|
92 | } |
---|
93 | /** |
---|
94 | * <code>PanelHolder</code> constructor. |
---|
95 | * @param id PanelHolder identifier |
---|
96 | * @param pModel PanelModel parent |
---|
97 | */ |
---|
98 | public PanelHolder(String id, PanelModel pModel) { |
---|
99 | this.id = id; |
---|
100 | pModel_ = pModel; |
---|
101 | } |
---|
102 | /** |
---|
103 | * <code>PanelHolder</code> constructor. This constructor has arguments to |
---|
104 | * pass <code>Map</code>s of <code>Label</code>, <code>DataGroup</code>, and |
---|
105 | * <code>Legend</code> objects. The <code>Map</code> key is the objects identifier. |
---|
106 | * @param id PanelHolder identifier |
---|
107 | * @param pModel PanelModel parent |
---|
108 | * @param bounds bounds |
---|
109 | * @param labels Map containing Labels |
---|
110 | * @param dataGroups Map containing DataGroups |
---|
111 | * @param legends Map contiaining Legends |
---|
112 | */ |
---|
113 | public PanelHolder(String id, PanelModel pModel, |
---|
114 | Rectangle bounds, |
---|
115 | Map labels, |
---|
116 | Map dataGroups, Map legends) { |
---|
117 | this.id = id; |
---|
118 | pModel_ = pModel; |
---|
119 | this.bounds = bounds; |
---|
120 | if(labels != null) { |
---|
121 | labels_ = new HashMap(labels); |
---|
122 | } |
---|
123 | if(dataGroups != null) { |
---|
124 | dataGroups_ = new HashMap(dataGroups); |
---|
125 | } |
---|
126 | if(legends != null) { |
---|
127 | legends_ = new HashMap(legends); |
---|
128 | } |
---|
129 | } |
---|
130 | /** |
---|
131 | * Set the <code>PanelModel</code> parent. |
---|
132 | * @param pModel PanelModel |
---|
133 | */ |
---|
134 | public void setPanelModel(PanelModel pModel) { |
---|
135 | if(pModel_ != null) removeChangeListener(pModel_); |
---|
136 | pModel_ = pModel; |
---|
137 | addChangeListener(pModel_); |
---|
138 | } |
---|
139 | /** |
---|
140 | * Get the <code>PanelModel</code>. |
---|
141 | * @return PanelModel |
---|
142 | */ |
---|
143 | public PanelModel getPanelModel() { |
---|
144 | return pModel_; |
---|
145 | } |
---|
146 | /** |
---|
147 | * Add <code>Label</code> to the <code>PanelHolder</code>. |
---|
148 | * @param label Label |
---|
149 | */ |
---|
150 | public void addLabel(Label label) { |
---|
151 | label.addChangeListener(this); |
---|
152 | label.setPanelHolder(this); |
---|
153 | labels_.put(label.getId(), label); |
---|
154 | fireStateChanged(); |
---|
155 | } |
---|
156 | /** |
---|
157 | * Remove <code>Label</code> from the <code>PanelHolder</code>. |
---|
158 | * @param label Label |
---|
159 | */ |
---|
160 | public void removeLabel(Label label) { |
---|
161 | label.removeAllChangeListeners(); |
---|
162 | labels_.remove(label.getId()); |
---|
163 | fireStateChanged(); |
---|
164 | } |
---|
165 | /** |
---|
166 | * Add <code>DataGroup</code> to the <code>PanelHolder</code>. |
---|
167 | * @param dataGroup DataGroup |
---|
168 | */ |
---|
169 | public void addDataGroup(DataGroup dataGroup) { |
---|
170 | dataGroup.addChangeListener(this); |
---|
171 | dataGroups_.put(dataGroup.getId(), dataGroup); |
---|
172 | fireStateChanged(); |
---|
173 | } |
---|
174 | /** |
---|
175 | * Remove <code>DataGroup</code> from the <code>PanelHolder</code>. |
---|
176 | * @param dataGroup DataGroup |
---|
177 | */ |
---|
178 | public void removeDataGroup(DataGroup dataGroup) { |
---|
179 | dataGroup.removeAllChangeListeners(); |
---|
180 | dataGroup.getXAxisHolder().removeAllChangeListeners(); |
---|
181 | dataGroup.getYAxisHolder().removeAllChangeListeners(); |
---|
182 | dataGroups_.remove(dataGroup.getId()); |
---|
183 | fireStateChanged(); |
---|
184 | } |
---|
185 | /** |
---|
186 | * Add <code>Legend</code> to the <code>PanelHolder</code>. |
---|
187 | * @param legend Legend |
---|
188 | */ |
---|
189 | public void addLegend(Legend legend) { |
---|
190 | legend.addChangeListener(this); |
---|
191 | legend.setPanelHolder(this); |
---|
192 | legends_.put(legend.getId(), legend); |
---|
193 | fireStateChanged(); |
---|
194 | } |
---|
195 | /** |
---|
196 | * Remove <code>Legend</code> from the <code>PanelHolder</code>. |
---|
197 | * @param legend Legend |
---|
198 | */ |
---|
199 | public void removeLegend(Legend legend) { |
---|
200 | legend.removeAllChangeListeners(); |
---|
201 | legends_.remove(legend.getId()); |
---|
202 | fireStateChanged(); |
---|
203 | } |
---|
204 | /** |
---|
205 | * Set <code>PanelHolder</code> identifier. |
---|
206 | * @param id identifier |
---|
207 | */ |
---|
208 | public void setId(String id) { |
---|
209 | String old = this.id; |
---|
210 | this.id = id; |
---|
211 | if(old == null || !old.equals(this.id)) fireStateChanged(); |
---|
212 | } |
---|
213 | /** |
---|
214 | * Get <code>PanelHolder</code> identifier |
---|
215 | * @return identifier |
---|
216 | */ |
---|
217 | public String getId() { |
---|
218 | return id; |
---|
219 | } |
---|
220 | /** |
---|
221 | * Get number of <code>Label</code> objects in <code>Map</code>. |
---|
222 | * @return number of Labels |
---|
223 | */ |
---|
224 | public int getLabelSize() { |
---|
225 | return labels_.size(); |
---|
226 | } |
---|
227 | /** |
---|
228 | * Get number of <code>DataGroup</code> objects in <code>Map</code>. |
---|
229 | * @return number of DataGroups |
---|
230 | */ |
---|
231 | public int getDataGroupSize() { |
---|
232 | return dataGroups_.size(); |
---|
233 | } |
---|
234 | /** |
---|
235 | * Get number of <code>Legend</code> objects in <code>Map</code>. |
---|
236 | * @return number of Legends |
---|
237 | */ |
---|
238 | public int getLegendSize() { |
---|
239 | return legends_.size(); |
---|
240 | } |
---|
241 | /** |
---|
242 | * Get an <code>Iterator</code> of <code>Label</code> objects. |
---|
243 | * @return Iterator |
---|
244 | */ |
---|
245 | public Iterator labelIterator() { |
---|
246 | return labels_.values().iterator(); |
---|
247 | } |
---|
248 | /** |
---|
249 | * Get an <code>Iterator</code> of <code>DataGroup</code> objects. |
---|
250 | * @return Iterator |
---|
251 | */ |
---|
252 | public Iterator dataGroupIterator() { |
---|
253 | return dataGroups_.values().iterator(); |
---|
254 | } |
---|
255 | /** |
---|
256 | * Get an <code>Iterator</code> of <code>Legend</code> objects. |
---|
257 | * @return Iterator |
---|
258 | */ |
---|
259 | public Iterator legendIterator() { |
---|
260 | return legends_.values().iterator(); |
---|
261 | } |
---|
262 | /** |
---|
263 | * Set bounds of <code>Panel</code>. |
---|
264 | * @param bounds bounds |
---|
265 | */ |
---|
266 | public void setBounds(Rectangle bounds) { |
---|
267 | Rectangle old = this.bounds; |
---|
268 | this.bounds = bounds; |
---|
269 | fireStateChanged(); |
---|
270 | } |
---|
271 | /** |
---|
272 | * Get bounds of <code>Panel</code>. |
---|
273 | * @return bounds |
---|
274 | */ |
---|
275 | public Rectangle getBounds() { |
---|
276 | return bounds; |
---|
277 | /** @todo bounds isn't cloned should be see note */ |
---|
278 | // return (Rectangle)bounds.clone(); // the clone didn't work with XMLEncoder for some reason |
---|
279 | } |
---|
280 | /** |
---|
281 | * Remove all <code>ChangeListener</code>s. |
---|
282 | */ |
---|
283 | public void removeAllChangeListeners() { |
---|
284 | changeListeners = null; |
---|
285 | } |
---|
286 | /** |
---|
287 | * <code>ChangeListner</code> callback. |
---|
288 | * @param e ChangeEvent |
---|
289 | */ |
---|
290 | public void stateChanged(ChangeEvent e) { |
---|
291 | if (changeListeners != null) { |
---|
292 | Vector listeners = changeListeners; |
---|
293 | int count = listeners.size(); |
---|
294 | for (int i = 0; i < count; i++) { |
---|
295 | ((ChangeListener) listeners.elementAt(i)).stateChanged(e); |
---|
296 | } |
---|
297 | } |
---|
298 | } |
---|
299 | /** |
---|
300 | * Remove changelistener. |
---|
301 | * @param l changelistener |
---|
302 | */ |
---|
303 | public synchronized void removeChangeListener(ChangeListener l) { |
---|
304 | if (changeListeners != null && changeListeners.contains(l)) { |
---|
305 | Vector v = (Vector) changeListeners.clone(); |
---|
306 | v.removeElement(l); |
---|
307 | changeListeners = v; |
---|
308 | } |
---|
309 | } |
---|
310 | /** |
---|
311 | * Add changelistener |
---|
312 | * @param l changelistener |
---|
313 | */ |
---|
314 | public synchronized void addChangeListener(ChangeListener l) { |
---|
315 | Vector v = changeListeners == null ? new Vector(2) : (Vector) changeListeners.clone(); |
---|
316 | if (!v.contains(l)) { |
---|
317 | v.addElement(l); |
---|
318 | changeListeners = v; |
---|
319 | } |
---|
320 | } |
---|
321 | /** |
---|
322 | * Remove all <code>ChangeListener</code>s that implement the |
---|
323 | * <code>DesignListener</code> interface. |
---|
324 | * |
---|
325 | * @see DesignListener |
---|
326 | */ |
---|
327 | public synchronized void removeDesignChangeListeners() { |
---|
328 | if(changeListeners != null) { |
---|
329 | Vector v = (Vector) changeListeners.clone(); |
---|
330 | Iterator iter = v.iterator(); |
---|
331 | while(iter.hasNext()) { |
---|
332 | Object obj = iter.next(); |
---|
333 | if(obj instanceof DesignListener) changeListeners.removeElement(obj); |
---|
334 | } |
---|
335 | } |
---|
336 | } |
---|
337 | |
---|
338 | protected void fireStateChanged() { |
---|
339 | if (changeListeners != null) { |
---|
340 | Vector listeners = changeListeners; |
---|
341 | int count = listeners.size(); |
---|
342 | for (int i = 0; i < count; i++) { |
---|
343 | ((ChangeListener) listeners.elementAt(i)).stateChanged(changeEvent_); |
---|
344 | } |
---|
345 | } |
---|
346 | } |
---|
347 | /** |
---|
348 | * Set <code>Panel</code> visible. |
---|
349 | * @param visible true if visible |
---|
350 | */ |
---|
351 | public void setVisible(boolean visible) { |
---|
352 | boolean saved = this.visible; |
---|
353 | this.visible = visible; |
---|
354 | if(saved != this.visible) fireStateChanged(); |
---|
355 | } |
---|
356 | /** |
---|
357 | * Is <code>Panel</code> visible? |
---|
358 | * @return true, if Panel is visible |
---|
359 | */ |
---|
360 | public boolean isVisible() { |
---|
361 | return visible; |
---|
362 | } |
---|
363 | /** |
---|
364 | * Set instantiated. Once associated <code>Panel</code> object has been created |
---|
365 | * this property is set true. Used internally. |
---|
366 | * @param instantiated true if instantiated |
---|
367 | */ |
---|
368 | public void setInstantiated(boolean instantiated) { |
---|
369 | this.instantiated = instantiated; |
---|
370 | } |
---|
371 | /** |
---|
372 | * Is panel instantiated? |
---|
373 | * @return true, if Panel instantiated |
---|
374 | */ |
---|
375 | public boolean isInstantiated() { |
---|
376 | return instantiated; |
---|
377 | } |
---|
378 | /** |
---|
379 | * Find a <code>DataGroup</code> by identifier. |
---|
380 | * @param id identifier |
---|
381 | * @return DataGroup |
---|
382 | */ |
---|
383 | public DataGroup findDataGroup(String id) { |
---|
384 | return (DataGroup)dataGroups_.get(id); |
---|
385 | } |
---|
386 | /** |
---|
387 | * Find <code>Label</code> by identifier. |
---|
388 | * @param id identifier |
---|
389 | * @return Label |
---|
390 | */ |
---|
391 | public Label findLabel(String id) { |
---|
392 | return (Label)labels_.get(id); |
---|
393 | } |
---|
394 | /** |
---|
395 | * Find <code>Legend</code> by identifier. |
---|
396 | * @param id identifier |
---|
397 | * @return Legend |
---|
398 | */ |
---|
399 | public Legend findLegend(String id) { |
---|
400 | return (Legend)legends_.get(id); |
---|
401 | } |
---|
402 | /** |
---|
403 | * Does <code>PanelHolder</code> contain <code>DataGroup</code>? |
---|
404 | * @param id DataGroup identifier |
---|
405 | * @return true, if DataGroup exists |
---|
406 | */ |
---|
407 | public boolean hasDataGroup(String id) { |
---|
408 | return dataGroups_.containsKey(id); |
---|
409 | } |
---|
410 | /** |
---|
411 | * Does <code>PanelHolder</code> contain <code>Label</code>? |
---|
412 | * @param id Label identifier |
---|
413 | * @return Label |
---|
414 | */ |
---|
415 | public boolean hasLabel(String id) { |
---|
416 | return labels_.containsKey(id); |
---|
417 | } |
---|
418 | /** |
---|
419 | * Does <code>PanelHolder</code> contain <code>Legend</code>? |
---|
420 | * @param id Legend identifier |
---|
421 | * @return Legend |
---|
422 | */ |
---|
423 | public boolean hasLegend(String id) { |
---|
424 | return legends_.containsKey(id); |
---|
425 | } |
---|
426 | /** |
---|
427 | * Return <code>Border</code> for <code>Panel</code>. |
---|
428 | * @return Border |
---|
429 | */ |
---|
430 | public Border getBorder() { |
---|
431 | return border; |
---|
432 | } |
---|
433 | /** |
---|
434 | * Set <code>Border</code> for <code>Panel</code>. Default = LineBorder(gray, 2) |
---|
435 | * @param border Border |
---|
436 | */ |
---|
437 | public void setBorder(Border border) { |
---|
438 | Border saved = this.border; |
---|
439 | this.border = border; |
---|
440 | if(saved == null || !saved.equals(this.border)) fireStateChanged(); |
---|
441 | } |
---|
442 | /** |
---|
443 | * Get <code>Map</code> of </code>Label</code>s. |
---|
444 | * @return Map |
---|
445 | */ |
---|
446 | public Map getLabels() { |
---|
447 | return labels_; |
---|
448 | } |
---|
449 | /** |
---|
450 | * Set <code>Map</code> of </code>Label</code>s. Key in <code>Map</code> contains |
---|
451 | * <code>Label</code> identifier. |
---|
452 | * @param labels Label Map |
---|
453 | */ |
---|
454 | public void setLabels(Map labels) { |
---|
455 | labels_ = labels; |
---|
456 | Iterator iter = labelIterator(); |
---|
457 | while(iter.hasNext()) { |
---|
458 | ((Label)iter.next()).addChangeListener(this); |
---|
459 | } |
---|
460 | fireStateChanged(); |
---|
461 | } |
---|
462 | /** |
---|
463 | * Get <code>Map</code> containing <code>Legend</code>s. |
---|
464 | * @return Map |
---|
465 | */ |
---|
466 | public Map getLegends() { |
---|
467 | return legends_; |
---|
468 | } |
---|
469 | /** |
---|
470 | * Set <code>Map</code> of </code>Legend</code>s. Key in <code>Map</code> contains |
---|
471 | * <code>Legend</code> identifier. |
---|
472 | * @param legends Legend Map |
---|
473 | */ |
---|
474 | public void setLegends(Map legends) { |
---|
475 | legends_ = legends; |
---|
476 | Iterator iter = legendIterator(); |
---|
477 | while(iter.hasNext()) { |
---|
478 | ((Legend)iter.next()).addChangeListener(this); |
---|
479 | } |
---|
480 | fireStateChanged(); |
---|
481 | } |
---|
482 | /** |
---|
483 | * Get <code>Map</code> containing <code>DataGroup</code>s. |
---|
484 | * @return Map |
---|
485 | */ |
---|
486 | public Map getDataGroups() { |
---|
487 | return dataGroups_; |
---|
488 | } |
---|
489 | /** |
---|
490 | * Set <code>Map</code> of </code>DataGroup</code>s. Key in <code>Map</code> contains |
---|
491 | * <code>DataGroup</code> identifier. |
---|
492 | * @param dataGroups DataGroup Map |
---|
493 | */ |
---|
494 | public void setDataGroups(Map dataGroups) { |
---|
495 | dataGroups_ = dataGroups; |
---|
496 | Iterator iter = dataGroupIterator(); |
---|
497 | while(iter.hasNext()) { |
---|
498 | ((DataGroup)iter.next()).addChangeListener(this); |
---|
499 | } |
---|
500 | fireStateChanged(); |
---|
501 | } |
---|
502 | /** |
---|
503 | * Get background color. Will use the page background if usePageBackground property |
---|
504 | * is true. |
---|
505 | * @return color |
---|
506 | */ |
---|
507 | public Color getBackground() { |
---|
508 | return background; |
---|
509 | } |
---|
510 | /** |
---|
511 | * Set the <code>Panel</code> background color. |
---|
512 | * @param background color |
---|
513 | */ |
---|
514 | public void setBackground(Color background) { |
---|
515 | Color saved = this.background; |
---|
516 | this.background = background; |
---|
517 | if(!saved.equals(this.background)) fireStateChanged(); |
---|
518 | } |
---|
519 | /** |
---|
520 | * Use the page background color? |
---|
521 | * @return true if using page background color |
---|
522 | */ |
---|
523 | public boolean isUsePageBackground() { |
---|
524 | return usePageBackground; |
---|
525 | } |
---|
526 | /** |
---|
527 | * Set the <code>Panel</code> to use the <code>Page</code> background color. |
---|
528 | * @param pageBackground true to use page background color |
---|
529 | */ |
---|
530 | public void setUsePageBackground(boolean pageBackground) { |
---|
531 | boolean saved = this.usePageBackground; |
---|
532 | this.usePageBackground = pageBackground; |
---|
533 | if(saved != this.usePageBackground) fireStateChanged(); |
---|
534 | } |
---|
535 | } |
---|