001: /*
002: * @(#)JGraphEllipseView.java 1.0 12-MAY-2004
003: *
004: * Copyright (c) 2001-2005, Gaudenz Alder
005: * All rights reserved.
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: */
022: package com.jgraph.example.fastgraph;
023:
024: import java.awt.BasicStroke;
025: import java.awt.Dimension;
026: import java.awt.GradientPaint;
027: import java.awt.Graphics;
028: import java.awt.Graphics2D;
029: import java.awt.Point;
030: import java.awt.geom.Point2D;
031: import java.awt.geom.Rectangle2D;
032:
033: import org.jgraph.graph.CellViewRenderer;
034: import org.jgraph.graph.GraphConstants;
035: import org.jgraph.graph.VertexRenderer;
036:
037: /**
038: * @author Gaudenz Alder
039: *
040: * TODO To change the template for this generated type comment go to
041: * Window - Preferences - Java - Code Generation - Code and Comments
042: */
043: public class FastCircleView extends FastVertexView {
044:
045: /**
046: * The renderer for this view
047: */
048: public static transient JGraphEllipseRenderer renderer = new JGraphEllipseRenderer();
049:
050: /**
051: * The default constructor
052: */
053: public FastCircleView() {
054: super ();
055: }
056:
057: /**
058: * Constructs a fast circle view associated this view with the specified
059: * cell
060: * @param cell the model cell to associated this view with
061: */
062: public FastCircleView(Object cell) {
063: super (cell);
064: }
065:
066: /**
067: * Returns the intersection of the bounding rectangle and the
068: * straight line between the source and the specified point p.
069: * The specified point is expected not to intersect the bounds.
070: */
071: public Point2D getPerimeterPoint(Point2D source, Point2D p) {
072: Rectangle2D r = getBounds();
073:
074: double x = r.getX();
075: double y = r.getY();
076: double a = (r.getWidth() + 1) / 2;
077: double b = (r.getHeight() + 1) / 2;
078:
079: // x0,y0 - center of ellipse
080: double x0 = x + a;
081: double y0 = y + b;
082:
083: // x1, y1 - point
084: double x1 = p.getX();
085: double y1 = p.getY();
086:
087: // calculate straight line equation through point and ellipse center
088: // y = d * x + h
089: double dx = x1 - x0;
090: double dy = y1 - y0;
091:
092: if (dx == 0)
093: return new Point((int) x0, (int) (y0 + b * dy
094: / Math.abs(dy)));
095:
096: double d = dy / dx;
097: double h = y0 - d * x0;
098:
099: // calculate intersection
100: double e = a * a * d * d + b * b;
101: double f = -2 * x0 * e;
102: double g = a * a * d * d * x0 * x0 + b * b * x0 * x0 - a * a
103: * b * b;
104:
105: double det = Math.sqrt(f * f - 4 * e * g);
106:
107: // two solutions (perimeter points)
108: double xout1 = (-f + det) / (2 * e);
109: double xout2 = (-f - det) / (2 * e);
110: double yout1 = d * xout1 + h;
111: double yout2 = d * xout2 + h;
112:
113: double dist1Squ = Math.pow((xout1 - x1), 2)
114: + Math.pow((yout1 - y1), 2);
115: double dist2Squ = Math.pow((xout2 - x1), 2)
116: + Math.pow((yout2 - y1), 2);
117:
118: // correct solution
119: double xout, yout;
120:
121: if (dist1Squ < dist2Squ) {
122: xout = xout1;
123: yout = yout1;
124: } else {
125: xout = xout2;
126: yout = yout2;
127: }
128:
129: return getAttributes().createPoint(xout, yout);
130: }
131:
132: /**
133: * @return the renderer for this view
134: */
135: public CellViewRenderer getRenderer() {
136: return renderer;
137: }
138:
139: /**
140: * The renderer for this view
141: */
142: public static class JGraphEllipseRenderer extends VertexRenderer {
143:
144: /**
145: * Return a slightly larger preferred size than for a rectangle.
146: */
147: public Dimension getPreferredSize() {
148: Dimension d = super .getPreferredSize();
149: d.width += d.width / 8;
150: d.height += d.height / 2;
151: return d;
152: }
153:
154: /**
155: * The method that draws the cell
156: */
157: public void paint(Graphics g) {
158: int b = borderWidth;
159: Graphics2D g2 = (Graphics2D) g;
160: Dimension d = getSize();
161: boolean tmp = selected;
162: if (super .isOpaque()) {
163: g.setColor(super .getBackground());
164: if (gradientColor != null && !preview) {
165: setOpaque(false);
166: g2.setPaint(new GradientPaint(0, 0,
167: getBackground(), getWidth(), getHeight(),
168: gradientColor, true));
169: }
170: g.fillOval(b - 1, b - 1, d.width - b, d.height - b);
171: }
172: try {
173: setBorder(null);
174: setOpaque(false);
175: selected = false;
176: super .paint(g);
177: } finally {
178: selected = tmp;
179: }
180: if (bordercolor != null) {
181: g.setColor(bordercolor);
182: g2.setStroke(new BasicStroke(b));
183: g.drawOval(b - 1, b - 1, d.width - b, d.height - b);
184: }
185: if (selected) {
186: g2.setStroke(GraphConstants.SELECTION_STROKE);
187: g.setColor(highlightColor);
188: g.drawOval(b - 1, b - 1, d.width - b, d.height - b);
189: }
190: }
191: }
192:
193: }
|