source: ether_statistics/service/implementation/gov/noaa/pmel/sgt/beans/PanelModel.java @ 569

Last change on this file since 569 was 569, checked in by vmipsl, 12 years ago

Nouveau projet

File size: 18.8 KB
Line 
1/*
2 * $Id: PanelModel.java,v 1.8 2003/09/18 21:01:14 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
13package gov.noaa.pmel.sgt.beans;
14
15import java.awt.Rectangle;
16import java.awt.Dimension;
17import java.awt.Color;
18import java.awt.Point;
19
20import java.util.List;
21import java.util.Vector;
22import java.util.Iterator;
23import java.util.Map;
24import java.util.HashMap;
25
26import java.beans.*;
27
28import gov.noaa.pmel.sgt.LayerChild;
29import gov.noaa.pmel.sgt.AbstractPane;
30import java.io.*;
31import javax.swing.event.ChangeEvent;
32import javax.swing.event.ChangeListener;
33import java.awt.event.ComponentEvent;
34import java.awt.event.ComponentListener;
35
36/**
37 * A model that supports the <code>Panel</code> structure of a <code>Plot</code>.
38 * Information includes the <code>DataGroup</code>s and <code>LayerChild</code>ren that
39 * are included in a <code>Panel</code>.  A <code>Panel</code> consist of several
40 * <code>Layer</code>s, at least one for each <code>DataGroup</code>.
41 * <p>
42 * The layout of the <code>Panel</code>s will eventually be accomplished using the <code>SpringLayout</code>.
43 * This will provide a flexible and easy method to position the <code>Panel</code>s
44 * in arbitrary positions.  Currently the <code>Panel</code>s are positioned in
45 * absolution location.
46 * <p> Some classes have been omitted for display purposes.
47 * <P ALIGN="CENTER"><IMG SRC="images/PanelModelSimple.png" ALIGN="BOTTOM" BORDER="0">
48 *
49 * @author Donald Denbo
50 * @version $Revision: 1.8 $, $Date: 2003/09/18 21:01:14 $
51 * @since 3.0
52 * @stereotype bean
53 **/
54public class PanelModel implements Serializable, ChangeListener, ComponentListener, PropertyChangeListener{
55  transient private PropertyChangeSupport support_ = new PropertyChangeSupport(this);
56  private Map panelList = new HashMap(4);
57  private float dpi = 72.0f; // pixel to user scale (dots per inch);
58  private Dimension pageSize = new Dimension(400, 300);
59  private Color pageBackgroundColor = Color.white;
60  private int printHAlign = AbstractPane.CENTER;
61  private int printVAlign = AbstractPane.TOP;
62  private int printMode = AbstractPane.DEFAULT_SCALE;
63  private Point printOrigin = new  Point(0, 0);
64  private boolean printBorders = false;
65  private boolean printWhitePage = true;
66  transient private boolean batch = false;
67  transient private boolean modified = false;
68//
69  transient private ChangeEvent changeEvent_ = new ChangeEvent(this);
70  transient private Vector changeListeners;
71
72  /**
73   * @label page
74   */
75  transient private Page page;
76
77  /** @link aggregation
78   * @supplierCardinality 1..*
79   * @label panelList*/
80  /*#PanelHolder lnkPanelHolder;*/
81
82  /**
83   * <code>PanelModel</code> constructor.
84   */
85  public PanelModel() {
86  }
87  /**
88   * Create a new <code>PanelModel</code> from an object serialized using
89   * <code>XMLEncoder</code>.  For example,
90   *
91   * <pre>
92   *   PanelModel pModel;
93   *   Page page = new Page();
94   *       try {
95   *    pModel = PanelModel.loadFromXML(new BufferedInputStream(
96   *                       new FileInputStream(outpath)));
97   *    page.setPanelModel(pModel);
98   *  } catch (FileNotFoundException fnfe) {
99   *    JOptionPane.showMessageDialog(this, "Error openning file",
100   *                                  "File Open Error", JOptionPane.ERROR_MESSAGE);
101   *  } catch (InvalidObjectException ioe) {
102   *    JOptionPane.showMessageDialog(this, "File does not contain a PanelModel",
103   *                                  "PanelModel Not Found",
104   *                                  JOptionPane.ERROR_MESSAGE);
105   *  }
106   *
107   * </pre>
108   * @param is InputStream
109   * @return PanelModel object
110   * @throws InvalidObjectException
111   * @see java.beans.XMLEncoder
112   */
113  static public PanelModel loadFromXML(InputStream is) throws InvalidObjectException {
114    PanelModel pModel = null;
115    XMLDecoder xd = new XMLDecoder(is);
116    Object obj = xd.readObject();
117    xd.close();
118    if(obj instanceof PanelModel) {
119      pModel = (PanelModel)obj;
120      pModel.repair();
121    } else {
122      throw new InvalidObjectException("XML file does not contain a PanelModel");
123    }
124    return pModel;
125  }
126  /**
127   * Save <code>PanelModel</code> and its supporting classes as a XML stream using
128   * the <code>XMLEncoder</code>.
129   * @param os OutputStream
130   */
131  public void saveToXML(OutputStream os) {
132    XMLEncoder xe = new XMLEncoder(os);
133    xe.writeObject(this);
134    xe.close();
135   }
136   /**
137    * Create a new <code>Panel</code> and add to <code>PanelModel</code>.
138    * @param id Panel identifier
139    * @param bounds bounds of Panel
140    * @param labels Label Map
141    * @param dataGroups DataGroup Map
142    * @param legends Legend Map
143    */
144   public void addPanel(String id, Rectangle bounds, Map labels,
145                       Map dataGroups, Map legends) {
146    PanelHolder ph = new PanelHolder(id, this, bounds, labels, dataGroups, legends);
147    addPanel(ph);
148  }
149  /**
150   * Add a <code>PanelHolder</code> to <code>PanelModel</code>.
151   * @param ph PanelHolder
152   */
153  public void addPanel(PanelHolder ph) {
154    int sze = panelList.size();
155    ph.addChangeListener(this);
156    panelList.put(ph.getId(), ph);
157    firePropertyChange("panelList", sze, panelList.size());
158  }
159  /**
160   * Remove Panel from <code>PanelModel</code>.
161   * @param ph PanelHolder
162   */
163  public void removePanel(PanelHolder ph) {
164    int sze = panelList.size();
165    ph.removeChangeListener(this);
166    panelList.remove(ph.getId());
167    firePropertyChange("panelList", sze, panelList.size());
168  }
169  /**
170   * Get <code>Iterator</code> of <code>PanelHolder</code> objects.
171   * @return Iterator
172   */
173  public Iterator panelIterator() {
174    return panelList.values().iterator();
175  }
176  /**
177   * Get number of <code>PanelHolder</code> objects in <code>Map</code>.
178   * @return count
179   */
180  public int getPanelCount() {
181    return panelList.size();
182  }
183  /**
184   * Does the <code>PanelModel</code> contain this <code>PanelHolder</code>?
185   * @param id PanelHolder identifier
186   * @return true, if PanelHolder exists.
187   */
188  public boolean hasPanelHolder(String id) {
189    return findPanelHolder(id) != null;
190  }
191  /**
192   * Find the <code>PanelHolder</code> from its  identifier.
193   * @param id PanelHolder identifier
194   * @return PanelHolder
195   */
196  public PanelHolder findPanelHolder(String id) {
197    return (PanelHolder)panelList.get(id);
198  }
199  /**
200  * Add property change listener.
201  * @param l property change listener
202  */
203  public void addPropertyChangeListener(PropertyChangeListener l) {
204    support_.addPropertyChangeListener(l);
205  }
206  /**
207   * Listen for specific property change.
208   * @param name property name
209   * @param l property change listner
210   */
211  public void addPropertyChangeListener(String name, PropertyChangeListener l) {
212    support_.addPropertyChangeListener(name, l);
213  }
214  /**
215   * Remove property change listener.
216   * @param l property change listener
217   */
218  public void removePropertyChangeListener(PropertyChangeListener l) {
219    support_.removePropertyChangeListener(l);
220  }
221  /**
222   * Remove specific property change listener
223   * @param name property name
224   * @param l property change listener
225   */
226  public void removePropertyChangeListener(String name, PropertyChangeListener l) {
227    support_.removePropertyChangeListener(name, l);
228  }
229  /**
230   * Get dots per inch value.
231   * @return dots per inch
232   */
233  public float getDpi() {
234    return dpi;
235  }
236
237  /**
238   * Set dots per inch.  Fires property "dpi" when changed.
239   * @param dpi dots per inch
240   */
241  public void setDpi(float dpi) {
242    float saved = this.dpi;
243    this.dpi = dpi;
244    if(saved != this.dpi) firePropertyChange("dpi", new Float(saved), new Float(this.dpi));
245  }
246  /**
247   * <code>ChangeListner</code> callback.
248   * @param e ChangeEvent
249   */
250  public void stateChanged(ChangeEvent e) {
251    Object source = e.getSource();
252    firePropertyChange("panel", null, source);
253  }
254
255  private void firePropertyChange(String name, Object oldValue, Object newValue) {
256    if(batch) {
257      modified = true;
258    } else {
259      support_.firePropertyChange(name, oldValue, newValue);
260    }
261  }
262
263  private void firePropertyChange(String name, int oldValue, int newValue) {
264    if(batch) {
265      modified = true;
266    } else {
267      support_.firePropertyChange(name, oldValue, newValue);
268    }
269  }
270  /**
271   * Set batching for changes to <code>PanelModel</code>. Fires property "batch"
272   * when <code>PanelModel</code> has changed and batch is set to false.
273   * @param batch batch value
274   */
275  public void setBatch(boolean batch) {
276    this.batch = batch;
277    if(!this.batch && modified) {
278      modified = false;
279      support_.firePropertyChange("batch", null, null);
280    }
281  }
282  /**
283   * Registers ChangeListeners and sets back references in <code>PanelModel</code> and
284   * its children.
285   */
286  private void repair() {
287    // traverse PanelModel and create all event links
288    Iterator iter = panelIterator();
289    while(iter.hasNext()) {
290      PanelHolder ph = (PanelHolder)iter.next();
291      ph.removeAllChangeListeners();
292      ph.addChangeListener(this);
293      ph.setPanelModel(this);
294      Iterator dgIter = ph.dataGroupIterator();
295      while(dgIter.hasNext()) {
296        DataGroup dg = (DataGroup)dgIter.next();
297        dg.removeAllChangeListeners();
298        dg.addChangeListener(ph);
299        dg.setPanelHolder(ph);
300        dg.getXAxisHolder().removeAllChangeListeners();
301        dg.getXAxisHolder().addChangeListener(dg);
302        dg.getXAxisHolder().setDataGroup(dg);
303        dg.getYAxisHolder().removeAllChangeListeners();
304        dg.getYAxisHolder().addChangeListener(dg);
305        dg.getYAxisHolder().setDataGroup(dg);
306      }
307      Iterator lbIter = ph.labelIterator();
308      while(lbIter.hasNext()) {
309        Label lb = (Label)lbIter.next();
310        lb.removeAllChangeListeners();
311        lb.addChangeListener(ph);
312        lb.setPanelHolder(ph);
313      }
314      Iterator lgIter = ph.legendIterator();
315      while(lgIter.hasNext()) {
316        Legend lg = (Legend)lgIter.next();
317        lg.removeAllChangeListeners();
318        lg.addChangeListener(ph);
319        lg.setPanelHolder(ph);
320      }
321    }
322  }
323  /**
324   * Is batching turned on?
325   * @return true, if batch is on
326   */
327  public boolean isBatch() {
328    return batch;
329  }
330  /**
331   * Set <code>Page</code> parent.  Called from <code>Page</code> when added to
332   * <code>Page</code> object.
333   * @param page Page
334   */
335  public void setPage(Page page) {
336    if(this.page != null) removePropertyChangeListener(this.page);
337    this.page = page;
338    addPropertyChangeListener(this.page);
339    page.addComponentListener(this);
340    page.addPropertyChangeListener(this);
341    pageSize = page.getSize();
342  }
343  /**
344   * Get Page parent
345   * @return Page
346   */
347  public Page getPage() {
348    return page;
349  }
350  /**
351   * Get <code>Map</code> containing <code>PanelHolder</code> objects.
352   * @return Map
353   */
354  public Map getPanelList() {
355    return panelList;
356  }
357  /**
358   * Set <code>PanelHolder</code> <code>Map</code>.
359   * @param panelList Map
360   */
361  public void setPanelList(Map panelList) {
362    if(Page.DEBUG) System.out.println("PanelModel.setPanelList(): size = " + panelList.size());
363    this.panelList = panelList;
364    Iterator iter = panelIterator();
365    while(iter.hasNext()) {
366      PanelHolder ph = (PanelHolder)iter.next();
367      ph.addChangeListener(this);
368    }
369    firePropertyChange("panelList", 0, panelList.size());  // should this be fired?
370  }
371  /**
372   * Get <code>Page</code> size.
373   * @return Page dimensions
374   */
375  public Dimension getPageSize() {
376    return pageSize;
377  }
378  /**
379   * Set <code>Page</code> size.
380   * @param pageSize Page dimension
381   */
382  public void setPageSize(Dimension pageSize) {
383    Dimension saved = this.pageSize;
384    this.pageSize = pageSize;
385    if(!saved.equals(this.pageSize)) {
386      firePropertyChange("pageSize", saved, pageSize);
387      fireStateChanged();
388    }
389  }
390  /**
391   * Listener to update <code>Page</code> size if it changes.
392   * @param e ComponentEvent
393   */
394  public void componentResized(ComponentEvent e) {
395    pageSize = page.getSize();
396  }
397  /**
398   * Unused.
399   */
400  public void componentMoved(ComponentEvent e) { }
401  /**
402   * Unused.
403   */
404  public void componentShown(ComponentEvent e) { }
405  /**
406   * Unused.
407   */
408  public void componentHidden(ComponentEvent e) { }
409  /**
410   * Get the background color for <code>Page</code>.
411   * @return color
412   */
413  public Color getPageBackgroundColor() {
414    return pageBackgroundColor;
415  }
416  /**
417   * Set <code>Page</code> background color.
418   * @param pageBackgroundColor background color
419   */
420  public void setPageBackgroundColor(Color pageBackgroundColor) {
421    Color saved = this.pageBackgroundColor;
422    this.pageBackgroundColor = pageBackgroundColor;
423    if(!saved.equals(this.pageBackgroundColor)) {
424      firePropertyChange("pageBackgroundColor", saved, this.pageBackgroundColor);
425      fireStateChanged();
426    }
427  }
428  /**
429   * Print borders?
430   * @return true, if borders will be printed
431   */
432  public boolean isPrintBorders() {
433    return printBorders;
434  }
435  /**
436   * Print with white background?
437   * @return true, print on white background
438   */
439  public boolean isPrintWhitePage() {
440    return printWhitePage;
441  }
442  /**
443   * Set the print borders property.  Default = false.
444   * @param printBorders true to print borders
445   */
446  public void setPrintBorders(boolean printBorders) {
447    boolean saved = this.printBorders;
448    this.printBorders = printBorders;
449    if(saved != this.printBorders)
450      firePropertyChange("printBorders", new Boolean(saved),
451                         new Boolean(this.printBorders));
452  }
453  /**
454   * Set the print  on white background property.  Default = true.
455   * @param printWhitePage true to use white for background color
456   */
457  public void setPrintWhitePage(boolean printWhitePage) {
458    boolean saved = this.printWhitePage;
459    this.printWhitePage = printWhitePage;
460    if(saved != this.printWhitePage)
461      firePropertyChange("printWhitePage", new Boolean(saved),
462                         new Boolean(this.printWhitePage));
463  }
464  public void propertyChange(PropertyChangeEvent evt) {
465    if(Page.DEBUG) System.out.println("PanelModel.propertyChange("+evt.getPropertyName()+")");
466  }
467  /**
468   * Remove changelistener.
469   * @param l changelistener
470   */
471  public synchronized void removeChangeListener(ChangeListener l) {
472    if (changeListeners != null && changeListeners.contains(l)) {
473      Vector v = (Vector) changeListeners.clone();
474      v.removeElement(l);
475      changeListeners = v;
476    }
477  }
478  /**
479   * Remove all <code>ChangeListener</code>s that implement the
480   * <code>DesignListener</code> interface.
481   *
482   * @see DesignListener
483   */
484  public synchronized void removeDesignChangeListeners() {
485    if(changeListeners != null) {
486      Vector v = (Vector) changeListeners.clone();
487      Iterator iter = v.iterator();
488      while(iter.hasNext()) {
489        Object obj = iter.next();
490        if(obj instanceof DesignListener) changeListeners.removeElement(obj);
491      }
492    }
493  }
494
495  /**
496   * Add changelistener
497   * @param l changelistener
498   */
499  public synchronized void addChangeListener(ChangeListener l) {
500    Vector v = changeListeners == null ? new Vector(2) : (Vector) changeListeners.clone();
501    if (!v.contains(l)) {
502      v.addElement(l);
503      changeListeners = v;
504    }
505  }
506  protected void fireStateChanged() {
507    if (changeListeners != null) {
508      Vector listeners = changeListeners;
509      int count = listeners.size();
510      for (int i = 0; i < count; i++) {
511        ((ChangeListener) listeners.elementAt(i)).stateChanged(changeEvent_);
512      }
513    }
514  }
515  /**
516   * Get horizontal alignment for printing.
517   * @return horizontal alignment
518   */
519  public int getPrintHAlign() {
520    return printHAlign;
521  }
522  /**
523   * Set horizontal alignment for printing.  Legal values are AbstractPane.LEFT,
524   * AbstractPane.CENTER, AbstractPane.RIGHT, and AbstractPane.SPECIFIED_LOCATION.
525   * Default = AbstractPane.CENTER.
526   * @param pageHAlign horizontal alignment
527   * @see gov.noaa.pmel.sgt.AbstractPane#LEFT AbstractPane.LEFT
528   * @see gov.noaa.pmel.sgt.AbstractPane#CENTER AbstractPane.CENTER
529   * @see gov.noaa.pmel.sgt.AbstractPane#RIGHT AbstractPane.RIGHT
530   * @see gov.noaa.pmel.sgt.AbstractPane#SPECIFIED_LOCATION AbstractPane.SPECIFIED_LOCATION
531   */
532  public void setPrintHAlign(int printHAlign) {
533    int saved = this.printHAlign;
534    this.printHAlign = printHAlign;
535    if(saved != this.printHAlign)
536      firePropertyChange("printHAlign", saved, this.printHAlign);
537  }
538  /**
539   * Set page origin for printing.  Will be used if the horizontal or vertical alignment is
540   * AbstractPane.SPECIFIED_LOCATION.  Default = (0,0).
541   * @param pageOrigin page origin
542   * @see gov.noaa.pmel.sgt.AbstractPane AbstractPane
543   */
544  public void setPrintOrigin(Point printOrigin) {
545    Point saved = this.printOrigin;
546    this.printOrigin = printOrigin;
547    if(!saved.equals(this.printOrigin))
548      firePropertyChange("printOrigin", saved, this.printOrigin);
549  }
550  /**
551   * Get page origin for printing.
552   * @return page origin.
553   */
554  public Point getPrintOrigin() {
555    return printOrigin;
556  }
557  /**
558   * Get vertical alignment for printing.
559   * @return vertical alignment.
560   */
561  public int getPrintVAlign() {
562    return printVAlign;
563  }
564  /**
565   * Set vertical  alignment for printing.  Legal values are AbstractPane.TOP,
566   * AbstractPane.MIDDLE, AbstractPane.BOTTOM, and AbstractPane.SPECIFIED_LOCATION.
567   * Default = AbstractPane.TOP;
568   * @param pageVAlign vertical alignment
569   * @see gov.noaa.pmel.sgt.AbstractPane#TOP AbstractPane.TOP
570   * @see gov.noaa.pmel.sgt.AbstractPane#MIDDLE AbstractPane.MIDDLE
571   * @see gov.noaa.pmel.sgt.AbstractPane#BOTTOM AbstractPane.BOTTOM
572   * @see gov.noaa.pmel.sgt.AbstractPane#SPECIFIED_LOCATION AbstractPane.SPECIFIED_LOCATION
573   */
574  public void setPrintVAlign(int printVAlign) {
575    int saved = this.printVAlign;
576    this.printVAlign = printVAlign;
577    if(saved != this.printVAlign)
578      firePropertyChange("printVAlign", saved, this.printVAlign);
579  }
580  /**
581   * Get printing scale mode.
582   * @return scale mode
583   */
584  public int getPrintScaleMode() {
585    return printMode;
586  }
587  /**
588   * Set printing  scale mode.  Legal values are AbstractPane.DEFAULT_SCALE,
589   * AbstractPane.TO_FIT, and AbstractPane.SHRINK_TO_FIT.  Default =
590   * AbstractPane.DEFAULT_SCALE.
591   * @param mode scale mode
592   * @see gov.noaa.pmel.sgt.AbstractPane#DEFAULT_SCALE AbstractPane.DEFAULT_SCALE
593   * @see gov.noaa.pmel.sgt.AbstractPane#TO_FIT AbstractPane.TO_FIT
594   * @see gov.noaa.pmel.sgt.AbstractPane#SHRINK_TO_FIT AbstractPane.SHRINK_TO_FIT
595   */
596  public void setPrintScaleMode(int mode) {
597    int saved = this.printMode;
598    this.printMode = mode;
599    if(saved != this.printMode)
600      firePropertyChange("printScaleMode", saved, this.printMode);
601  }
602}
Note: See TracBrowser for help on using the repository browser.