/*
* $Id: Panel.java,v 1.8 2003/09/17 23:16:45 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.Graphics;
import java.awt.Component;
import java.awt.Rectangle;
import java.awt.Color;
import java.awt.Point;
import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;
import java.util.Vector;
import java.util.Collection;
import javax.swing.JComponent;
import javax.swing.border.Border;
import org.freehep.graphics2d.VectorGraphics;
import sgtplot.AbstractPane;
import sgtplot.Attribute;
import sgtplot.ChildNotFoundException;
import sgtplot.ColorKey;
import sgtplot.DataKey;
import sgtplot.JPane;
import sgtplot.Layer;
import sgtplot.LayerChild;
import sgtplot.LayerControl;
import sgtplot.LineKey;
import sgtplot.PaneNotFoundException;
import sgtplot.PointCollectionKey;
import sgtplot.Ruler;
import sgtplot.SGLabel;
import sgtplot.StackedLayout;
import sgtplot.VectorKey;
import sgtplot.dm.SGTData;
import sgtplot.util.Dimension2D;
import sgtplot.util.Point2D;
import sgtplot.util.Rectangle2D;
/**
* A Layer container that provides a StackedLayout of
* the Layers.
*
* @author Donald Denbo
* @version $Revision: 1.8 $, $Date: 2003/09/17 23:16:45 $
* @since 3.0
* @stereotype container
**/
public class Panel extends JComponent implements LayerControl {
/**
* @label pane
*/
private JPane pane_ = null;
/**
* @directed
* @label pHolder
*/
private PanelHolder pHolder_ = null;
/**
* @label labelLayer
*/
private Layer labelLayer_ = null;
/**
* @label legendLayer
*/
private Layer legendLayer_ = null;
/** @link aggregation
* @supplierCardinality * */
/*#DataGroupLayer lnkDataGroupLayer; */
private Map dataGroupLayerList_ = new HashMap(2);
/**
* Panel constructor. PanelHolder will need to be
* set.
* @param name Panel name
*/
public Panel(String name) {
super();
setName(name);
setLayout(new StackedLayout());
}
/**
* Panel constructor with PanelHolder argument.
* Panel name set from PanelHolder identifier.
* @param ph PanelHolder
*/
public Panel(PanelHolder ph) {
this(ph.getId());
pHolder_ = ph;
update();
}
/**
* Set PanelHolder. PanelHolder contains the layout
* information and DataGroups associated with the Panel.
* @param ph PanelHolder
*/
public void setPanelHolder(PanelHolder ph) {
pHolder_ = ph;
setName(pHolder_.getId());
update();
}
/**
* Traverses the PanelHolder and adds any new objects and
* updates exisiting objects.
*/
public void update() {
float dpi = pHolder_.getPanelModel().getDpi();
setBounds(pHolder_.getBounds());
double width = getBounds().width/dpi;
double height = getBounds().height/dpi;
Dimension2D psize = new Dimension2D(width, height);
if(pane_ != null) {
boolean batch = pane_.isBatch();
pane_.setBatch(true);
if(labelLayer_ == null) {
labelLayer_ = new Layer("Label Layer", psize);
add(labelLayer_);
labelLayer_.setPane(pane_);
} else {
labelLayer_.setSizeP(psize);
}
if(legendLayer_ == null) {
legendLayer_ = new Layer("Legend Layer", psize);
add(legendLayer_);
legendLayer_.setPane(pane_);
} else {
legendLayer_.setSizeP(psize);
}
this.setBorder(pHolder_.getBorder());
invalidate();
try {
updateLabels();
updateLegends();
updateDataGroups();
} catch (ChildNotFoundException e) {
e.printStackTrace();
}
pane_.setBatch(batch);
}
}
private void updateLabels() throws ChildNotFoundException {
Iterator lbIter = pHolder_.labelIterator();
// remove deleted labels from layer
// note cant remove from an Iterator!
LayerChild[] children = labelLayer_.getChildren();
for(int i=0; i < children.length; i++) {
LayerChild child = children[i];
if(!pHolder_.hasLabel(child.getId())) {
labelLayer_.removeChild(child);
}
}
// add or update labels to layer
while(lbIter.hasNext()) {
SGLabel sgl = null;
Label label = (Label)lbIter.next();
LayerChild child = labelLayer_.findChild(label.getId());
Point2D.Double loc = label.getLocationP();
Rectangle2D.Double bnds = label.getBoundsP();
double hgt;
if(label.getOrientation() == SGLabel.HORIZONTAL) {
hgt = label.getHeightP();
switch(label.getJustification()) {
case SGLabel.LEFT:
break;
case SGLabel.CENTER:
loc.x = loc.x + bnds.getWidth()*0.5;
break;
case SGLabel.RIGHT:
loc.x = loc.x + bnds.getWidth();
break;
}
} else {
hgt = label.getWidthP();
loc.x += bnds.getWidth();
switch(label.getJustification()) {
case SGLabel.LEFT:
break;
case SGLabel.CENTER:
loc.y = loc.y + bnds.getHeight()*0.5;
break;
case SGLabel.RIGHT:
loc.y = loc.y + bnds.getHeight();
break;
}
}
if(child == null) {
sgl = new SGLabel(label.getId(),
label.getText(),
hgt,
loc,
SGLabel.BOTTOM,
label.getJustification());
sgl.setVisible(label.isVisible());
sgl.setSelectable(label.isSelectable());
sgl.setOrientation(label.getOrientation());
sgl.setColor(label.getColor());
sgl.setFont(label.getFont());
labelLayer_.addChild(sgl);
label.setInstantiated(true);
} else {
sgl = (SGLabel)child;
sgl.setText(label.getText());
sgl.setHeightP(hgt);
sgl.setLocationP(loc);
sgl.setHAlign(label.getJustification());
sgl.setVisible(label.isVisible());
sgl.setSelectable(label.isSelectable());
sgl.setOrientation(label.getOrientation());
sgl.setColor(label.getColor());
sgl.setFont(label.getFont());
}
}
}
private void updateLegends() {
Iterator lgIter = pHolder_.legendIterator();
while(lgIter.hasNext()) {
DataKey key = null;
Legend legend = (Legend)lgIter.next();
LayerChild child = legendLayer_.findChild(legend.getId());
Rectangle2D.Double boundsP = legend.getBoundsP();
if(child == null) {
switch(legend.getType()) {
case Legend.LINE:
key = new LineKey(legend.getLocationP(),
LineKey.TOP, LineKey.LEFT);
break;
case Legend.COLOR:
key = new ColorKey(legend.getLocationP(),
new Dimension2D(boundsP.width, boundsP.height),
ColorKey.TOP, ColorKey.LEFT);
break;
case Legend.VECTOR:
key = new VectorKey(legend.getLocationP(),
VectorKey.TOP, VectorKey.LEFT);
break;
case Legend.POINT:
key = new PointCollectionKey(legend.getLocationP(),
PointCollectionKey.TOP, PointCollectionKey.LEFT);
break;
}
key.setId(legend.getId());
legendLayer_.addChild(key);
legend.setInstantiated(true);
} else {
key = (DataKey)child;
key.setLocationP(legend.getLocationP());
// key.setBoundsP(legend.getBoundsP());
}
if(legend.isColor()) {
ColorKey ckey = (ColorKey)key;
ckey.setSizeP(new Dimension2D(boundsP.width, boundsP.height));
Ruler scale = ckey.getRuler();
scale.setLabelColor(legend.getScaleColor());
scale.setLineColor(legend.getScaleColor());
scale.setLabelFont(legend.getScaleLabelFont());
scale.setLabelHeightP(legend.getScaleLabelHeightP());
scale.setLabelInterval(legend.getScaleLabelInterval());
scale.setNumberSmallTics(legend.getScaleNumberSmallTics());
scale.setLargeTicHeightP(legend.getScaleLargeTicHeightP());
scale.setSmallTicHeightP(legend.getScaleSmallTicHeightP());
scale.setSignificantDigits(legend.getScaleSignificantDigits());
scale.setLabelFormat(legend.getScaleLabelFormat());
scale.setVisible(legend.isScaleVisible());
if(boundsP.width >= boundsP.height) {
ckey.setOrientation(ColorKey.HORIZONTAL);
} else {
ckey.setOrientation(ColorKey.VERTICAL);
}
}
key.setBorderStyle(legend.getBorderStyle());
key.setColumns(legend.getColumns());
key.setLineLengthP(legend.getLineLength());
key.setVisible(legend.isVisible());
}
}
private void updateDataGroups() {
float dpi = pHolder_.getPanelModel().getDpi();
setBounds(pHolder_.getBounds());
double width = getBounds().width/dpi;
double height = getBounds().height/dpi;
Dimension2D psize = new Dimension2D(width, height);
Iterator dgIter = pHolder_.dataGroupIterator();
// remove delete DataGroups from panel/pane
Component[] comps = getComponents();
for(int i=0; i < comps.length; i++) {
if(comps[i] instanceof Layer) {
Layer ly = (Layer)comps[i];
if(ly != labelLayer_ && ly != legendLayer_) {
if(!pHolder_.hasDataGroup(ly.getId())) {
this.remove(ly);
}
}
}
}
// create/update DataGroup layers
while(dgIter.hasNext()) {
DataGroup ag = (DataGroup)dgIter.next();
// find DataGroupLayer
DataGroupLayer dgl = findDataGroupLayer(ag.getId());
if(dgl == null) {
dgl = new DataGroupLayer(this, ag);
add(dgl);
dgl.setSizeP(psize);
ag.setInstantiated(true);
dataGroupLayerList_.put(dgl.getId(), dgl);
} else {
dgl.update();
}
}
}
/**
* Find object associated with a MOUSE_DOWN event. The getObjectAt method
* scans through all the objects associated with the Panel to find one
* whose bounding box contains the mouse location.
*
* This method should not be called by a user.
*
* @param x mouse coordinate
* @param y mouse coordinate
* @param check if true requires that object isSelectable
* @return object at location
**/
public Object getObjectAt(int x, int y, boolean check) {
Object obj = null;
obj = labelLayer_.getObjectAt(x, y, check);
if(obj != null) return obj;
obj = legendLayer_.getObjectAt(x, y, check);
if(obj != null) return obj;
Iterator iter = dataGroupLayerList_.values().iterator();
while(iter.hasNext()) {
obj = ((DataGroupLayer)iter.next()).getObjectAt(x, y, check);
if(obj != null) return obj;
}
return obj;
}
/**
* Zoom DataGroupLayers in Panel.
* Zoom to Rectangle if zoom operation started within bounds.
* @param start start point
* @param rect zoom rectangle
*/
void zoomTo(Point start, Rectangle rect) {
Iterator iter = dataGroupLayerList_.values().iterator();
while(iter.hasNext()) {
((DataGroupLayer)iter.next()).zoomTo(start, rect);
}
}
/**
* Reset the zoom for DataGroupLayers in this Panel
* if it contains the point.
* @param x x device coordinate
* @param y y device coordinate
*/
void resetZoom(int x, int y) {
Iterator iter = dataGroupLayerList_.values().iterator();
while(iter.hasNext()) {
((DataGroupLayer)iter.next()).resetZoom(x, y);
}
}
/**
* Reset the zoom for all DataGroupLayers in this Panel.
*/
public void resetZoom() {
Iterator iter = dataGroupLayerList_.values().iterator();
while(iter.hasNext()) {
((DataGroupLayer)iter.next()).resetZoom();
}
}
/**
* Set clipping for DataGroupLayers in this Panel.
* @param clip if true clip data to bounds.
*/
public void setClipping(boolean clip) {
Iterator iter = dataGroupLayerList_.values().iterator();
while(iter.hasNext()) {
((DataGroupLayer)iter.next()).setClipping(clip);
}
}
/**
* Does this Panel contain this Layer?
* @param id layer identification
* @return true, if Layer is in Panel
*/
public boolean hasLayer(String id) {
if(id.equals(labelLayer_.getId())) return true;
if(id.equals(legendLayer_.getId())) return true;
Iterator iter = dataGroupLayerList_.values().iterator();
while(iter.hasNext()) {
if(id.equals(((DataGroupLayer)iter.next()).getId())) return true;
}
return false;
}
/**
* Get Layer from this Panel. Returns null
* if Layer is not found.
* @param id Layer identifier
* @return Layer
*/
public Layer getLayer(String id) {
if(id.equals(labelLayer_.getId())) return labelLayer_;
if(id.equals(legendLayer_.getId())) return legendLayer_;
Iterator iter = dataGroupLayerList_.values().iterator();
while(iter.hasNext()) {
DataGroupLayer dgl = (DataGroupLayer)iter.next();
if(id.equals(dgl.getId())) return dgl;
}
return null;
}
/**
* Checks to see if a data id matches that data attached to the
* Graph.
* @param id data identifier
* @return true if data is in Panel
*/
public boolean isDataInPanel(String id) {
Iterator iter = dataGroupLayerList_.values().iterator();
while(iter.hasNext()) {
DataGroupLayer dgl = (DataGroupLayer)iter.next();
if(dgl.isDataInLayer(id)) return true;
}
return false;
}
/**
* Get Layer from this Panel. Returns null
* if Layer is not found.
* @param id SGTData identifier
* @return Layer
*/
public Layer getLayerFromDataId(String id) {
Iterator iter = dataGroupLayerList_.values().iterator();
while(iter.hasNext()) {
DataGroupLayer dgl = (DataGroupLayer)iter.next();
if(dgl.isDataInLayer(id)) return dgl;
}
return null;
}
/**
* Find objects associated with a MOUSE_DOWN event. The getObjecstAt method
* scans through all the objects associated with the Panel to find those
* whose bounding box contains the mouse location.
*
* This method should not be called by a user.
*
* @param x mouse coordinate
* @param y mouse coordinate
* @param check if selectable
* @return object array
*/
public Object[] getObjectsAt(int x, int y, boolean check) {
Object[] obj = null;
Vector obList = new Vector();
obj = labelLayer_.getObjectsAt(x, y, check);
if(obj != null) {
for(int i=0; i < obj.length; i++) {
obList.addElement(obj[i]);
}
}
obj = legendLayer_.getObjectsAt(x, y, check);
if(obj != null) {
for(int i=0; i < obj.length; i++) {
obList.addElement(obj[i]);
}
}
Iterator iter = dataGroupLayerList_.values().iterator();
while(iter.hasNext()) {
obj = ((DataGroupLayer)iter.next()).getObjectsAt(x, y, check);
if(obj != null) {
for(int i=0; i < obj.length; i++) {
obList.addElement(obj[i]);
}
}
}
return obList.toArray();
}
/**
* Find DataGroupLayer in Panel.
* @param id DataGroupLayer identifier
* @return DataGroupLayer
*/
public DataGroupLayer findDataGroupLayer(String id) {
return (DataGroupLayer)dataGroupLayerList_.get(id);
}
/**
* Get the JPane the Panel is associated
* with.
*
* @return Refence to the Pane
**/
public JPane getPane() {
return pane_;
}
/**
* Set the Pane the Panel is associated with.
* This method is called by Pane when the
* Pane.add method is exectued.
*
* @param pane The Pane
**/
public void setPane(AbstractPane pane) {
pane_ = (JPane)pane;
update();
}
public void draw(Graphics g) throws PaneNotFoundException {
VectorGraphics vg = VectorGraphics.create(g);
if(!pHolder_.isUsePageBackground()) {
Color saved = vg.getColor();
Rectangle r = pHolder_.getBounds();
vg.setColor(pHolder_.getBackground());
vg.fillRect(r.x, r.y, r.width, r.height);
vg.setColor(saved);
}
Component[] comps = this.getComponents();
for(int i=0; i < comps.length; i++) {
if(comps[i] instanceof LayerControl) {
((LayerControl)comps[i]).draw(vg);
}
}
}
public void drawDraggableItems(VectorGraphics g) throws PaneNotFoundException {
Component[] comps = this.getComponents();
for(int i=0; i < comps.length; i++) {
if(comps[i] instanceof LayerControl) {
((LayerControl)comps[i]).drawDraggableItems(g);
}
}
}
/**
* Add data to this Panel and DataGroup. legend can
* be null.
* @param data SGTData to be added
* @param attr Attribute
* @param dataGroup DataGroup to add data to
* @param legend Lenged for data
* @throws DataTargetMismatchException
*/
public void addData(SGTData data, Attribute attr,
DataGroup dataGroup, Legend legend)
throws DataTargetMismatchException {
DataGroupLayer agLayer = findDataGroupLayer(dataGroup.getId());
DataKey key = null;
if(legend != null) key = (DataKey)legendLayer_.findChild(legend.getId());
agLayer.addData(data, attr, key);
}
/**
* Get the identifier for the Panel
* @return identifier/name
*/
public String getId() {
return getName();
}
/**
* Get a String representation of the
* Layer.
*
* @return String representation
*/
public String toString() {
String name = getClass().getName();
return name.substring(name.lastIndexOf(".")+1) + ": " + pHolder_.getId();
}
@Override
public void draw(VectorGraphics g) throws PaneNotFoundException {
// TODO Auto-generated method stub
}
}
Ads help maintain this website.