/*
 * $Id: PanelModel.java,v 1.8 2003/09/18 21:01:14 dwd Exp $
 *
 * This software is provided by NOAA for full, free and open release.  It is
 * understood by the recipient/user that NOAA assumes no liability for any
 * errors contained in the code.  Although this software is released without
 * conditions or restrictions in its use, it is expected that appropriate
 * credit be given to its author and to the National Oceanic and Atmospheric
 * Administration should the software be included by the recipient as an
 * element in other product development.
 */

package sgtplot.beans;

import java.awt.Rectangle;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.Point;

import java.util.List;
import java.util.Vector;
import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;

import java.beans.*;

import java.io.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import sgtplot.AbstractPane;
import sgtplot.LayerChild;

import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;

/**
 * A model that supports the Panel structure of a Plot.
 * Information includes the DataGroups and LayerChildren that
 * are included in a Panel.  A Panel consist of several
 * Layers, at least one for each DataGroup.
 * 

* The layout of the Panels will eventually be accomplished using the SpringLayout. * This will provide a flexible and easy method to position the Panels * in arbitrary positions. Currently the Panels are positioned in * absolution location. *

Some classes have been omitted for display purposes. *

* * @author Donald Denbo * @version $Revision: 1.8 $, $Date: 2003/09/18 21:01:14 $ * @since 3.0 * @stereotype bean **/ public class PanelModel implements Serializable, ChangeListener, ComponentListener, PropertyChangeListener{ transient private PropertyChangeSupport support_ = new PropertyChangeSupport(this); private Map panelList = new HashMap(4); private float dpi = 72.0f; // pixel to user scale (dots per inch); private Dimension pageSize = new Dimension(400, 300); private Color pageBackgroundColor = Color.white; private int printHAlign = AbstractPane.CENTER; private int printVAlign = AbstractPane.TOP; private int printMode = AbstractPane.DEFAULT_SCALE; private Point printOrigin = new Point(0, 0); private boolean printBorders = false; private boolean printWhitePage = true; transient private boolean batch = false; transient private boolean modified = false; // transient private ChangeEvent changeEvent_ = new ChangeEvent(this); transient private Vector changeListeners; /** * @label page */ transient private Page page; /** @link aggregation * @supplierCardinality 1..* * @label panelList*/ /*#PanelHolder lnkPanelHolder;*/ /** * PanelModel constructor. */ public PanelModel() { } /** * Create a new PanelModel from an object serialized using * XMLEncoder. For example, * *

   *   PanelModel pModel;
   *   Page page = new Page();
   *       try {
   *    pModel = PanelModel.loadFromXML(new BufferedInputStream(
   *                       new FileInputStream(outpath)));
   *    page.setPanelModel(pModel);
   *  } catch (FileNotFoundException fnfe) {
   *    JOptionPane.showMessageDialog(this, "Error openning file",
   *                                  "File Open Error", JOptionPane.ERROR_MESSAGE);
   *  } catch (InvalidObjectException ioe) {
   *    JOptionPane.showMessageDialog(this, "File does not contain a PanelModel",
   *                                  "PanelModel Not Found",
   *                                  JOptionPane.ERROR_MESSAGE);
   *  }
   *
   * 
* @param is InputStream * @return PanelModel object * @throws InvalidObjectException * @see java.beans.XMLEncoder */ static public PanelModel loadFromXML(InputStream is) throws InvalidObjectException { PanelModel pModel = null; XMLDecoder xd = new XMLDecoder(is); Object obj = xd.readObject(); xd.close(); if(obj instanceof PanelModel) { pModel = (PanelModel)obj; pModel.repair(); } else { throw new InvalidObjectException("XML file does not contain a PanelModel"); } return pModel; } /** * Save PanelModel and its supporting classes as a XML stream using * the XMLEncoder. * @param os OutputStream */ public void saveToXML(OutputStream os) { XMLEncoder xe = new XMLEncoder(os); xe.writeObject(this); xe.close(); } /** * Create a new Panel and add to PanelModel. * @param id Panel identifier * @param bounds bounds of Panel * @param labels Label Map * @param dataGroups DataGroup Map * @param legends Legend Map */ public void addPanel(String id, Rectangle bounds, Map labels, Map dataGroups, Map legends) { PanelHolder ph = new PanelHolder(id, this, bounds, labels, dataGroups, legends); addPanel(ph); } /** * Add a PanelHolder to PanelModel. * @param ph PanelHolder */ public void addPanel(PanelHolder ph) { int sze = panelList.size(); ph.addChangeListener(this); panelList.put(ph.getId(), ph); firePropertyChange("panelList", sze, panelList.size()); } /** * Remove Panel from PanelModel. * @param ph PanelHolder */ public void removePanel(PanelHolder ph) { int sze = panelList.size(); ph.removeChangeListener(this); panelList.remove(ph.getId()); firePropertyChange("panelList", sze, panelList.size()); } /** * Get Iterator of PanelHolder objects. * @return Iterator */ public Iterator panelIterator() { return panelList.values().iterator(); } /** * Get number of PanelHolder objects in Map. * @return count */ public int getPanelCount() { return panelList.size(); } /** * Does the PanelModel contain this PanelHolder? * @param id PanelHolder identifier * @return true, if PanelHolder exists. */ public boolean hasPanelHolder(String id) { return findPanelHolder(id) != null; } /** * Find the PanelHolder from its identifier. * @param id PanelHolder identifier * @return PanelHolder */ public PanelHolder findPanelHolder(String id) { return (PanelHolder)panelList.get(id); } /** * Add property change listener. * @param l property change listener */ public void addPropertyChangeListener(PropertyChangeListener l) { support_.addPropertyChangeListener(l); } /** * Listen for specific property change. * @param name property name * @param l property change listner */ public void addPropertyChangeListener(String name, PropertyChangeListener l) { support_.addPropertyChangeListener(name, l); } /** * Remove property change listener. * @param l property change listener */ public void removePropertyChangeListener(PropertyChangeListener l) { support_.removePropertyChangeListener(l); } /** * Remove specific property change listener * @param name property name * @param l property change listener */ public void removePropertyChangeListener(String name, PropertyChangeListener l) { support_.removePropertyChangeListener(name, l); } /** * Get dots per inch value. * @return dots per inch */ public float getDpi() { return dpi; } /** * Set dots per inch. Fires property "dpi" when changed. * @param dpi dots per inch */ public void setDpi(float dpi) { float saved = this.dpi; this.dpi = dpi; if(saved != this.dpi) firePropertyChange("dpi", new Float(saved), new Float(this.dpi)); } /** * ChangeListner callback. * @param e ChangeEvent */ public void stateChanged(ChangeEvent e) { Object source = e.getSource(); firePropertyChange("panel", null, source); } private void firePropertyChange(String name, Object oldValue, Object newValue) { if(batch) { modified = true; } else { support_.firePropertyChange(name, oldValue, newValue); } } private void firePropertyChange(String name, int oldValue, int newValue) { if(batch) { modified = true; } else { support_.firePropertyChange(name, oldValue, newValue); } } /** * Set batching for changes to PanelModel. Fires property "batch" * when PanelModel has changed and batch is set to false. * @param batch batch value */ public void setBatch(boolean batch) { this.batch = batch; if(!this.batch && modified) { modified = false; support_.firePropertyChange("batch", null, null); } } /** * Registers ChangeListeners and sets back references in PanelModel and * its children. */ private void repair() { // traverse PanelModel and create all event links Iterator iter = panelIterator(); while(iter.hasNext()) { PanelHolder ph = (PanelHolder)iter.next(); ph.removeAllChangeListeners(); ph.addChangeListener(this); ph.setPanelModel(this); Iterator dgIter = ph.dataGroupIterator(); while(dgIter.hasNext()) { DataGroup dg = (DataGroup)dgIter.next(); dg.removeAllChangeListeners(); dg.addChangeListener(ph); dg.setPanelHolder(ph); dg.getXAxisHolder().removeAllChangeListeners(); dg.getXAxisHolder().addChangeListener(dg); dg.getXAxisHolder().setDataGroup(dg); dg.getYAxisHolder().removeAllChangeListeners(); dg.getYAxisHolder().addChangeListener(dg); dg.getYAxisHolder().setDataGroup(dg); } Iterator lbIter = ph.labelIterator(); while(lbIter.hasNext()) { Label lb = (Label)lbIter.next(); lb.removeAllChangeListeners(); lb.addChangeListener(ph); lb.setPanelHolder(ph); } Iterator lgIter = ph.legendIterator(); while(lgIter.hasNext()) { Legend lg = (Legend)lgIter.next(); lg.removeAllChangeListeners(); lg.addChangeListener(ph); lg.setPanelHolder(ph); } } } /** * Is batching turned on? * @return true, if batch is on */ public boolean isBatch() { return batch; } /** * Set Page parent. Called from Page when added to * Page object. * @param page Page */ public void setPage(Page page) { if(this.page != null) removePropertyChangeListener(this.page); this.page = page; addPropertyChangeListener(this.page); page.addComponentListener(this); page.addPropertyChangeListener(this); pageSize = page.getSize(); } /** * Get Page parent * @return Page */ public Page getPage() { return page; } /** * Get Map containing PanelHolder objects. * @return Map */ public Map getPanelList() { return panelList; } /** * Set PanelHolder Map. * @param panelList Map */ public void setPanelList(Map panelList) { if(Page.DEBUG) System.out.println("PanelModel.setPanelList(): size = " + panelList.size()); this.panelList = panelList; Iterator iter = panelIterator(); while(iter.hasNext()) { PanelHolder ph = (PanelHolder)iter.next(); ph.addChangeListener(this); } firePropertyChange("panelList", 0, panelList.size()); // should this be fired? } /** * Get Page size. * @return Page dimensions */ public Dimension getPageSize() { return pageSize; } /** * Set Page size. * @param pageSize Page dimension */ public void setPageSize(Dimension pageSize) { Dimension saved = this.pageSize; this.pageSize = pageSize; if(!saved.equals(this.pageSize)) { firePropertyChange("pageSize", saved, pageSize); fireStateChanged(); } } /** * Listener to update Page size if it changes. * @param e ComponentEvent */ public void componentResized(ComponentEvent e) { pageSize = page.getSize(); } /** * Unused. */ public void componentMoved(ComponentEvent e) { } /** * Unused. */ public void componentShown(ComponentEvent e) { } /** * Unused. */ public void componentHidden(ComponentEvent e) { } /** * Get the background color for Page. * @return color */ public Color getPageBackgroundColor() { return pageBackgroundColor; } /** * Set Page background color. * @param pageBackgroundColor background color */ public void setPageBackgroundColor(Color pageBackgroundColor) { Color saved = this.pageBackgroundColor; this.pageBackgroundColor = pageBackgroundColor; if(!saved.equals(this.pageBackgroundColor)) { firePropertyChange("pageBackgroundColor", saved, this.pageBackgroundColor); fireStateChanged(); } } /** * Print borders? * @return true, if borders will be printed */ public boolean isPrintBorders() { return printBorders; } /** * Print with white background? * @return true, print on white background */ public boolean isPrintWhitePage() { return printWhitePage; } /** * Set the print borders property. Default = false. * @param printBorders true to print borders */ public void setPrintBorders(boolean printBorders) { boolean saved = this.printBorders; this.printBorders = printBorders; if(saved != this.printBorders) firePropertyChange("printBorders", new Boolean(saved), new Boolean(this.printBorders)); } /** * Set the print on white background property. Default = true. * @param printWhitePage true to use white for background color */ public void setPrintWhitePage(boolean printWhitePage) { boolean saved = this.printWhitePage; this.printWhitePage = printWhitePage; if(saved != this.printWhitePage) firePropertyChange("printWhitePage", new Boolean(saved), new Boolean(this.printWhitePage)); } public void propertyChange(PropertyChangeEvent evt) { if(Page.DEBUG) System.out.println("PanelModel.propertyChange("+evt.getPropertyName()+")"); } /** * Remove changelistener. * @param l changelistener */ public synchronized void removeChangeListener(ChangeListener l) { if (changeListeners != null && changeListeners.contains(l)) { Vector v = (Vector) changeListeners.clone(); v.removeElement(l); changeListeners = v; } } /** * Remove all ChangeListeners that implement the * DesignListener interface. * * @see DesignListener */ public synchronized void removeDesignChangeListeners() { if(changeListeners != null) { Vector v = (Vector) changeListeners.clone(); Iterator iter = v.iterator(); while(iter.hasNext()) { Object obj = iter.next(); if(obj instanceof DesignListener) changeListeners.removeElement(obj); } } } /** * Add changelistener * @param l changelistener */ public synchronized void addChangeListener(ChangeListener l) { Vector v = changeListeners == null ? new Vector(2) : (Vector) changeListeners.clone(); if (!v.contains(l)) { v.addElement(l); changeListeners = v; } } protected void fireStateChanged() { if (changeListeners != null) { Vector listeners = changeListeners; int count = listeners.size(); for (int i = 0; i < count; i++) { ((ChangeListener) listeners.elementAt(i)).stateChanged(changeEvent_); } } } /** * Get horizontal alignment for printing. * @return horizontal alignment */ public int getPrintHAlign() { return printHAlign; } /** * Set horizontal alignment for printing. Legal values are AbstractPane.LEFT, * AbstractPane.CENTER, AbstractPane.RIGHT, and AbstractPane.SPECIFIED_LOCATION. * Default = AbstractPane.CENTER. * @param pageHAlign horizontal alignment * @see sgtplot.AbstractPane#LEFT AbstractPane.LEFT * @see sgtplot.AbstractPane#CENTER AbstractPane.CENTER * @see sgtplot.AbstractPane#RIGHT AbstractPane.RIGHT * @see sgtplot.AbstractPane#SPECIFIED_LOCATION AbstractPane.SPECIFIED_LOCATION */ public void setPrintHAlign(int printHAlign) { int saved = this.printHAlign; this.printHAlign = printHAlign; if(saved != this.printHAlign) firePropertyChange("printHAlign", saved, this.printHAlign); } /** * Set page origin for printing. Will be used if the horizontal or vertical alignment is * AbstractPane.SPECIFIED_LOCATION. Default = (0,0). * @param pageOrigin page origin * @see sgtplot.AbstractPane AbstractPane */ public void setPrintOrigin(Point printOrigin) { Point saved = this.printOrigin; this.printOrigin = printOrigin; if(!saved.equals(this.printOrigin)) firePropertyChange("printOrigin", saved, this.printOrigin); } /** * Get page origin for printing. * @return page origin. */ public Point getPrintOrigin() { return printOrigin; } /** * Get vertical alignment for printing. * @return vertical alignment. */ public int getPrintVAlign() { return printVAlign; } /** * Set vertical alignment for printing. Legal values are AbstractPane.TOP, * AbstractPane.MIDDLE, AbstractPane.BOTTOM, and AbstractPane.SPECIFIED_LOCATION. * Default = AbstractPane.TOP; * @param pageVAlign vertical alignment * @see sgtplot.AbstractPane#TOP AbstractPane.TOP * @see sgtplot.AbstractPane#MIDDLE AbstractPane.MIDDLE * @see sgtplot.AbstractPane#BOTTOM AbstractPane.BOTTOM * @see sgtplot.AbstractPane#SPECIFIED_LOCATION AbstractPane.SPECIFIED_LOCATION */ public void setPrintVAlign(int printVAlign) { int saved = this.printVAlign; this.printVAlign = printVAlign; if(saved != this.printVAlign) firePropertyChange("printVAlign", saved, this.printVAlign); } /** * Get printing scale mode. * @return scale mode */ public int getPrintScaleMode() { return printMode; } /** * Set printing scale mode. Legal values are AbstractPane.DEFAULT_SCALE, * AbstractPane.TO_FIT, and AbstractPane.SHRINK_TO_FIT. Default = * AbstractPane.DEFAULT_SCALE. * @param mode scale mode * @see sgtplot.AbstractPane#DEFAULT_SCALE AbstractPane.DEFAULT_SCALE * @see sgtplot.AbstractPane#TO_FIT AbstractPane.TO_FIT * @see sgtplot.AbstractPane#SHRINK_TO_FIT AbstractPane.SHRINK_TO_FIT */ public void setPrintScaleMode(int mode) { int saved = this.printMode; this.printMode = mode; if(saved != this.printMode) firePropertyChange("printScaleMode", saved, this.printMode); } }

Ads help maintain this website.