View Javadoc

1   package com.bluecove.emu.gui.graph;
2   
3   import java.awt.BasicStroke;
4   import java.awt.Dimension;
5   import java.awt.GradientPaint;
6   import java.awt.Graphics;
7   import java.awt.Graphics2D;
8   import java.awt.Point;
9   import java.awt.Rectangle;
10  import java.awt.geom.Point2D;
11  import java.awt.geom.Rectangle2D;
12  
13  import org.jgraph.graph.CellViewRenderer;
14  import org.jgraph.graph.EdgeView;
15  import org.jgraph.graph.GraphConstants;
16  import org.jgraph.graph.VertexRenderer;
17  import org.jgraph.graph.VertexView;
18  
19  public class DeviceCellView extends VertexView {
20  
21  	public static transient JGraphEllipseRenderer renderer = new JGraphEllipseRenderer();
22  
23  	public static final int IMAGE_HEIGHT = 48;
24  	public static final int IMAGE_WIDTH = 48;
25  	private static final int IMAGE_VERTICAL_OFFSET = 16;
26  	
27  	public DeviceCellView() {
28  		super();
29  	}
30  
31  	public DeviceCellView(Object cell) {
32  		super(cell);
33  	}
34  
35  	private Rectangle2D getImageBounds() {
36  		Rectangle2D original = getBounds();
37  		int x = (int)(original.getX() + (original.getWidth() - IMAGE_WIDTH)/2);
38  		int y = (int)(original.getY()) + IMAGE_VERTICAL_OFFSET;
39  		return new Rectangle(x, y, IMAGE_WIDTH, IMAGE_HEIGHT);
40  	}
41  	
42  	public Point2D getPerimeterPoint(EdgeView edge, Point2D source, Point2D p) {
43  		Rectangle2D r = getImageBounds();
44  
45  		double x = r.getX();
46  		double y = r.getY();
47  		double a = (r.getWidth() + 1) / 2;
48  		double b = (r.getHeight() + 1) / 2;
49  
50  		// x0,y0 - center of ellipse
51  		double x0 = x + a;
52  		double y0 = y + b;
53  
54  		// x1, y1 - point
55  		double x1 = p.getX();
56  		double y1 = p.getY();
57  
58  		// calculate straight line equation through point and ellipse center
59  		// y = d * x + h
60  		double dx = x1 - x0;
61  		double dy = y1 - y0;
62  
63  		if (dx == 0)
64  			return new Point((int) x0, (int) (y0 + b * dy / Math.abs(dy)));
65  
66  		double d = dy / dx;
67  		double h = y0 - d * x0;
68  
69  		// calculate intersection
70  		double e = a * a * d * d + b * b;
71  		double f = -2 * x0 * e;
72  		double g = a * a * d * d * x0 * x0 + b * b * x0 * x0 - a * a * b * b;
73  
74  		double det = Math.sqrt(f * f - 4 * e * g);
75  
76  		// two solutions (perimeter points)
77  		double xout1 = (-f + det) / (2 * e);
78  		double xout2 = (-f - det) / (2 * e);
79  		double yout1 = d * xout1 + h;
80  		double yout2 = d * xout2 + h;
81  
82  		double dist1Squared = Math.pow((xout1 - x1), 2)
83  				+ Math.pow((yout1 - y1), 2);
84  		double dist2Squared = Math.pow((xout2 - x1), 2)
85  				+ Math.pow((yout2 - y1), 2);
86  
87  		// correct solution
88  		double xout, yout;
89  
90  		if (dist1Squared < dist2Squared) {
91  			xout = xout1;
92  			yout = yout1;
93  		} else {
94  			xout = xout2;
95  			yout = yout2;
96  		}
97  
98  		return getAttributes().createPoint(xout, yout);
99  	}
100 
101 	/**
102 	 */
103 	public CellViewRenderer getRenderer() {
104 		return renderer;
105 	}
106 
107 	/**
108 	 */
109 	public static class JGraphEllipseRenderer extends VertexRenderer {
110 
111 		/**
112 		 * Return a slightly larger preferred size than for a rectangle.
113 		 */
114 		public Dimension getPreferredSize() {
115 			Dimension d = super.getPreferredSize();
116 			d.width += d.width / 8;
117 			d.height += d.height / 2;
118 			return d;
119 		}
120 
121 		/**
122 		 */
123 		public void paint(Graphics g) {
124 			int b = borderWidth;
125 			Graphics2D g2 = (Graphics2D) g;
126 			
127 			int x = (int)((getSize().getWidth() - IMAGE_WIDTH)/2);
128 			int y = IMAGE_VERTICAL_OFFSET;
129 		
130 			boolean tmp = selected;
131 			if (super.isOpaque()) {
132 				g.setColor(super.getBackground());
133 				if (gradientColor != null && !preview) {
134 					setOpaque(false);
135 					g2.setPaint(new GradientPaint(0, 0, getBackground(),
136 							getWidth(), getHeight(), gradientColor, true));
137 				}
138 				g.fillOval(x + b - 1, y + b - 1, IMAGE_WIDTH - b, IMAGE_HEIGHT - b);
139 			}
140 			try {
141 				setBorder(null);
142 				setOpaque(false);
143 				selected = false;
144 				super.paint(g);
145 			} finally {
146 				selected = tmp;
147 			}
148 			if (bordercolor != null) {
149 				g.setColor(bordercolor);
150 				g2.setStroke(new BasicStroke(b));
151 				g.drawOval(x + b - 1, y + b - 1, IMAGE_WIDTH - b, IMAGE_HEIGHT - b);
152 			}
153 			if (selected) {
154 				g2.setStroke(GraphConstants.SELECTION_STROKE);
155 				g.setColor(highlightColor);
156 				g.drawOval(x + b - 1, y + b - 1, IMAGE_WIDTH - b, IMAGE_HEIGHT - b);
157 			}
158 		}
159 	}
160 }