/*
Violet - A program for editing UML diagrams.
Copyright (C) 2002 Cay S. Horstmann (http://horstmann.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.horstmann.violet.framework;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Point2D;
import java.beans.DefaultPersistenceDelegate;
import java.beans.Encoder;
import java.beans.Statement;
import java.util.ArrayList;
import java.util.List;
/**
A class that supplies convenience implementations for
a number of methods in the Node interface
*/
public abstract class AbstractNode implements Node
{
/**
Constructs a node with no parents or children.
*/
public AbstractNode()
{
children = new ArrayList();
parentNode = null;
}
public Object clone()
{
try
{
AbstractNode cloned = (AbstractNode)super.clone();
cloned.children = new ArrayList(children.size());
for (int i = 0; i < children.size(); i++)
{
Node n = (Node)children.get(i);
cloned.children.set(i, n.clone());
n.setParent(cloned);
}
return cloned;
}
catch (CloneNotSupportedException exception)
{
return null;
}
}
public void translate(double dx, double dy)
{
for (int i = 0; i < children.size(); i++)
{
Node n = (Node)children.get(i);
n.translate(dx, dy);
}
}
public boolean addEdge(Edge e, Point2D p1, Point2D p2)
{
return e.getEnd() != null;
}
public void removeEdge(Graph g, Edge e)
{
}
public void removeNode(Graph g, Node e)
{
if (e == parentNode) parentNode = null;
if (e.getParent() == this) children.remove(e);
}
public void layout(Graph g, Graphics2D g2, Grid grid)
{
}
public boolean addNode(Node n, Point2D p)
{
return false;
}
public Node getParent() { return parentNode; }
public void setParent(Node node) { parentNode = node; }
public List getChildren() { return children; }
public void addChild(int index, Node node)
{
Node oldParent = node.getParent();
if (oldParent != null)
oldParent.removeChild(node);
children.add(index, node);
node.setParent(this);
}
public void addChild(Node node)
{
addChild(children.size(), node);
}
public void removeChild(Node node)
{
if (node.getParent() != this) return;
children.remove(node);
node.setParent(null);
}
public void draw(Graphics2D g2)
{
Shape shape = getShape();
if (shape == null) return;
/*
Area shadow = new Area(shape);
shadow.transform(AffineTransform.getTranslateInstance(SHADOW_GAP, SHADOW_GAP));
shadow.subtract(new Area(shape));
*/
Color oldColor = g2.getColor();
g2.translate(SHADOW_GAP, SHADOW_GAP);
g2.setColor(SHADOW_COLOR);
g2.fill(shape);
g2.translate(-SHADOW_GAP, -SHADOW_GAP);
g2.setColor(g2.getBackground());
g2.fill(shape);
g2.setColor(oldColor);
}
private static final Color SHADOW_COLOR = Color.LIGHT_GRAY;
public static final int SHADOW_GAP = 4;
/**
@return the shape to be used for computing the drop shadow
*/
public Shape getShape() { return null; }
/**
Adds a persistence delegate to a given encoder that
encodes the child nodes of this node.
@param encoder the encoder to which to add the delegate
*/
public static void setPersistenceDelegate(Encoder encoder)
{
encoder.setPersistenceDelegate(AbstractNode.class, new
DefaultPersistenceDelegate()
{
protected void initialize(Class type,
Object oldInstance, Object newInstance,
Encoder out)
{
super.initialize(type, oldInstance,
newInstance, out);
Node n = (Node)oldInstance;
List children = n.getChildren();
for (int i = 0; i < children.size(); i++)
{
Node c = (Node)children.get(i);
out.writeStatement(
new Statement(oldInstance,
"addChild", new Object[]{ c }) );
}
}
});
}
private ArrayList children;
private Node parentNode;
}