Source of RectangularNode.java


  1: import java.awt.Graphics2D;
  2: import java.awt.geom.Point2D;
  3: import java.awt.geom.Rectangle2D;
  4: import java.awt.geom.RectangularShape;
  5: import java.io.IOException;
  6: import java.io.ObjectInputStream;
  7: import java.io.ObjectOutputStream;

  9: /**
 10:    A node that has a rectangular shape.
 11: */
 12: public abstract class RectangularNode implements Node
 13: {
 14:    public Object clone()
 15:    {
 16:       try
 17:       {
 18:          RectangularNode cloned = (RectangularNode) super.clone();
 19:          cloned.bounds = (Rectangle2D) bounds.clone();
 20:          return cloned;      
 21:       }
 22:       catch (CloneNotSupportedException exception)
 23:       {
 24:          return null;
 25:       }    
 26:    }

 28:    public void translate(double dx, double dy)
 29:    {
 30:       bounds.setFrame(bounds.getX() + dx,
 31:          bounds.getY() + dy, 
 32:          bounds.getWidth(), 
 33:          bounds.getHeight());
 34:    }

 36:    public boolean contains(Point2D p)
 37:    {
 38:       return bounds.contains(p);
 39:    }

 41:    public Rectangle2D getBounds()
 42:    {
 43:       return (Rectangle2D) bounds.clone();
 44:    }

 46:    public void setBounds(Rectangle2D newBounds)
 47:    {
 48:       bounds = newBounds;
 49:    }

 51:    public Point2D getConnectionPoint(Point2D aPoint)
 52:    {
 53:       double slope = bounds.getHeight() / bounds.getWidth();
 54:       double x = bounds.getCenterX();
 55:       double y = bounds.getCenterY();
 56:       double ex = aPoint.getX() - x;
 57:       double ey = aPoint.getY() - y;
 58:       
 59:       if (ex != 0 && -slope <= ey / ex && ey / ex <= slope)
 60:       {  
 61:          // intersects at left or right boundary
 62:          if (ex > 0) 
 63:          {
 64:             x = bounds.getMaxX();
 65:             y += (bounds.getWidth() / 2) * ey / ex;
 66:          }
 67:          else
 68:          {
 69:             x = bounds.getX();
 70:             y -= (bounds.getWidth() / 2) * ey / ex;
 71:          }
 72:       }
 73:       else if (ey != 0)
 74:       {  
 75:          // intersects at top or bottom
 76:          if (ey > 0) 
 77:          {
 78:             x += (bounds.getHeight() / 2) * ex / ey;
 79:             y = bounds.getMaxY();
 80:          }
 81:          else
 82:          {
 83:             x -= (bounds.getHeight() / 2) * ex / ey;
 84:             y = bounds.getY();
 85:          }
 86:       }
 87:       return new Point2D.Double(x, y);
 88:    }

 90:    private void writeObject(ObjectOutputStream out)
 91:       throws IOException
 92:    {
 93:       out.defaultWriteObject();
 94:       writeRectangularShape(out, bounds);
 95:    }

 97:    /**
 98:       A helper method to overcome the problem that the 2D shapes
 99:       aren't serializable. It writes x, y, width and height
100:       to the stream.
101:       @param out the stream
102:       @param s the shape      
103:    */
104:    private static void writeRectangularShape(
105:       ObjectOutputStream out, 
106:       RectangularShape s)
107:       throws IOException
108:    {
109:       out.writeDouble(s.getX());
110:       out.writeDouble(s.getY());
111:       out.writeDouble(s.getWidth());
112:       out.writeDouble(s.getHeight());
113:    }

115:    private void readObject(ObjectInputStream in)
116:       throws IOException, ClassNotFoundException
117:    {
118:       in.defaultReadObject();
119:       bounds = new Rectangle2D.Double();
120:       readRectangularShape(in, bounds);
121:    }
122:    
123:    /**
124:       A helper method to overcome the problem that the 2D shapes
125:       aren't serializable. It reads x, y, width and height
126:       from the stream.
127:       @param in the stream
128:       @param s the shape whose frame is set from the stream values
129:    */
130:    private static void readRectangularShape(ObjectInputStream in,
131:       RectangularShape s)
132:       throws IOException
133:    {
134:       double x = in.readDouble();
135:       double y = in.readDouble();
136:       double width = in.readDouble();
137:       double height = in.readDouble();
138:       s.setFrame(x, y, width, height);
139:    }

141:    private transient Rectangle2D bounds;
142: }