001: package com.xoetrope.carousel.survey;
002:
003: import java.awt.BasicStroke;
004: import java.awt.Color;
005: import java.awt.Component;
006: import java.awt.Font;
007: import java.awt.Graphics;
008: import java.awt.Graphics2D;
009: import java.awt.Point;
010: import java.awt.Polygon;
011: import java.awt.RenderingHints;
012: import java.awt.event.MouseEvent;
013: import java.awt.event.MouseListener;
014: import java.awt.event.MouseMotionListener;
015: import java.awt.geom.Rectangle2D;
016: import java.util.Enumeration;
017: import java.util.Vector;
018: import javax.swing.JComponent;
019: import javax.swing.JLayeredPane;
020: import javax.swing.SwingUtilities;
021: import net.xoetrope.xui.XProject;
022: import net.xoetrope.xui.XProjectManager;
023:
024: /**
025: * A view of the line connection two question group views or connecting
026: * rule view with target question group view.
027: *
028: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
029: * the GNU Public License (GPL), please see license.txt for more details. If
030: * you make commercial use of this software you must purchase a commercial
031: * license from Xoetrope.</p>
032: * <p> $Revision: 1.5 $</p>
033: */
034: public class XLine extends JComponent implements MouseListener,
035: MouseMotionListener {
036: public static Color LINE_COLOR = Color.BLACK;
037: public static Color DRAG_COLOR = Color.RED;
038: public static double ARLEN = 25;
039: public static double ARANG = 20;
040:
041: protected int orientation;
042: protected XRulesEditorPane editorPane;
043: protected boolean mousePressed;
044: protected boolean mouseDragged;
045: protected MouseEvent firstMouseEvent;
046: protected Polygon shape;
047: protected Point dragPoint;
048: protected XSource source;
049: protected XGroupView groupView;
050: protected XGroupView intersectedGroupView;
051: protected double arLen;
052:
053: protected static double getScale() {
054: return XRulesEditorPane.SCALE;
055: }
056:
057: public XLine(XSource s, XGroupView gv, XRulesEditorPane ep) {
058: super ();
059: source = s;
060: groupView = gv;
061: intersectedGroupView = null;
062: editorPane = ep;
063: mousePressed = false;
064: mouseDragged = false;
065: firstMouseEvent = null;
066: dragPoint = null;
067: shape = null;
068: arLen = ARLEN;
069: addMouseListener(this );
070: addMouseMotionListener(this );
071: editorPane.add(this , JLayeredPane.PALETTE_LAYER);
072: setLocation();
073: }
074:
075: public void setLocation() {
076: if (groupView == null)
077: return;
078:
079: orientation = 0;
080: int x = 10, y = 10, w = 10, h = 10;
081:
082: int gx1 = (mouseDragged ? (int) dragPoint.getX()
083: : (int) groupView.getLocation().getX());
084: int gy1 = (mouseDragged ? (int) dragPoint.getY()
085: : (int) groupView.getLocation().getY());
086: int gx2 = gx1
087: + (mouseDragged ? 0 : (int) groupView.getSize()
088: .getWidth());
089: int gy2 = gy1
090: + (mouseDragged ? 0 : (int) groupView.getSize()
091: .getHeight());
092:
093: int gx = (gx1 + gx2) / 2;
094: int gy = (gy1 + gy2) / 2;
095:
096: int gix = 0, giy = 0;
097: Point sourcePoint = source.getCenterPoint();
098: int rix = sourcePoint.x, riy = sourcePoint.y;
099: int dx = rix - gx;
100: int dy = riy - gy;
101: double xy = (double) dx / dy;
102: double yx = (double) dy / dx;
103:
104: if (rix <= gx) {
105: if (riy <= gy) {
106: orientation = 1;
107: giy = (int) ((gx1 - rix) * yx + riy);
108: gix = (int) ((gy1 - riy) * xy + rix);
109: if (giy >= gy1 && giy <= gy2)
110: gix = gx1;
111: else
112: giy = gy1;
113: } else {
114: orientation = 2;
115: giy = (int) ((gx1 - rix) * yx + riy);
116: gix = (int) ((gy2 - riy) * xy + rix);
117: if (giy >= gy1 && giy <= gy2)
118: gix = gx1;
119: else
120: giy = gy2;
121: }
122: } else {
123: if (riy <= gy) {
124: orientation = 3;
125: giy = (int) ((gx2 - rix) * yx + riy);
126: gix = (int) ((gy1 - riy) * xy + rix);
127: if (giy >= gy1 && giy <= gy2)
128: gix = gx2;
129: else
130: giy = gy1;
131: } else {
132: orientation = 4;
133: giy = (int) ((gx2 - rix) * yx + riy);
134: gix = (int) ((gy2 - riy) * xy + rix);
135: if (giy >= gy1 && giy <= gy2)
136: gix = gx2;
137: else
138: giy = gy2;
139: }
140: }
141:
142: int arLen = (int) getArLen();
143: w = Math.abs(rix - gix) + 2 * arLen;
144: h = Math.abs(riy - giy) + 2 * arLen;
145: x = Math.min(rix, gix) - arLen;
146: y = Math.min(riy, giy) - arLen;
147:
148: setSize(w, h);
149: setLocation(x, y);
150: }
151:
152: protected void paintLine(Graphics2D g) {
153: g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
154: RenderingHints.VALUE_ANTIALIAS_ON);
155: if (mouseDragged && intersectedGroupView == null)
156: g.setColor(DRAG_COLOR);
157: else
158: g.setColor(LINE_COLOR);
159:
160: int w = (int) getSize().getWidth();
161: int h = (int) getSize().getHeight();
162:
163: int marg = (int) getArLen();
164: w -= 2 * marg;
165: h -= 2 * marg;
166:
167: double rad = Math.toRadians(ARANG);
168: double a = (w != 0 ? Math.atan((double) h / w) : Math.PI / 2);
169:
170: int x0 = 0;
171: int y0 = 0;
172: double arLen = getArLen();
173: int x1 = (int) (Math.cos(a - rad) * arLen);
174: int y1 = (int) (Math.sin(a - rad) * arLen);
175: int x2 = (int) (Math.cos(a + rad) * arLen);
176: int y2 = (int) (Math.sin(a + rad) * arLen);
177: int x3 = 0;
178: int y3 = 0;
179:
180: w += marg;
181: h += marg;
182:
183: switch (orientation) {
184: case 1:
185: x0 = marg;
186: y0 = marg;
187: x1 = w - x1;
188: y1 = h - y1;
189: x2 = w - x2;
190: y2 = h - y2;
191: x3 = w;
192: y3 = h;
193: break;
194: case 2:
195: x0 = marg;
196: y0 = h;
197: x1 = w - x1;
198: y1 = y1 + marg;
199: x2 = w - x2;
200: y2 = y2 + marg;
201: x3 = w;
202: y3 = marg;
203: break;
204: case 3:
205: x0 = w;
206: y0 = marg;
207: x1 = x1 + marg;
208: y1 = h - y1;
209: x2 = x2 + marg;
210: y2 = h - y2;
211: x3 = marg;
212: y3 = h;
213: break;
214: case 4:
215: x0 = w;
216: y0 = h;
217: x1 = x1 + marg;
218: y1 = y1 + marg;
219: x2 = x2 + marg;
220: y2 = y2 + marg;
221: x3 = marg;
222: y3 = marg;
223: break;
224: }
225:
226: int[] xPoints = { x1, x3, x2 };
227: int[] yPoints = { y1, y3, y2 };
228: g.drawLine(x0, y0, x3, y3);
229: g.fillPolygon(xPoints, yPoints, 3);
230:
231: int dx = (x1 - x2);
232: int dy = (y1 - y2);
233: int px1 = x0 - dx;
234: int py1 = y0 - dy;
235: int px2 = x0 + dx;
236: int py2 = y0 + dy;
237: int px3 = x3 - dx;
238: int py3 = y3 - dy;
239: int px4 = x3 + dx;
240: int py4 = y3 + dy;
241: int[] pxPoints = { px1, px2, px3, px4 };
242: int[] pyPoints = { py1, py2, py3, py4 };
243: shape = new Polygon(pxPoints, pyPoints, 4);
244: }
245:
246: public void paint(Graphics g) {
247: Graphics2D g2d = (Graphics2D) g;
248: paintLine(g2d);
249: }
250:
251: public boolean contains(int x, int y) {
252: return (shape != null && shape.contains(new Point(x, y)));
253: }
254:
255: public XGroupView getGroupView() {
256: return groupView;
257: }
258:
259: public void setGroupView(XGroupView gv) {
260: groupView = gv;
261: }
262:
263: public XSource getSource() {
264: return source;
265: }
266:
267: public double getArLen() {
268: return getScale() * arLen;
269: }
270:
271: public void setArLen(double al) {
272: arLen = al / getScale();
273: }
274:
275: public void mouseClicked(MouseEvent e) {
276: }
277:
278: public void mousePressed(MouseEvent e) {
279: editorPane.moveToFront(this );
280: source.moveToFront();
281: firstMouseEvent = e;
282: mousePressed = true;
283: }
284:
285: public void mouseReleased(MouseEvent e) {
286: mousePressed = false;
287: mouseDragged = false;
288: firstMouseEvent = null;
289: if (intersectedGroupView != null
290: && !intersectedGroupView.equals(groupView)) {
291: groupView.removeTargetLine(this );
292: groupView = intersectedGroupView;
293: source.targetChanged(intersectedGroupView);
294: groupView.addTargetLine(this );
295: }
296: setLocation();
297: editorPane.repaint();
298: }
299:
300: public void mouseEntered(MouseEvent e) {
301: }
302:
303: public void mouseExited(MouseEvent e) {
304: }
305:
306: public void mouseDragged(MouseEvent e) {
307: if (!mousePressed)
308: return;
309:
310: mouseDragged = true;
311: dragPoint = SwingUtilities.convertPoint(this , e.getPoint(),
312: editorPane);
313: intersectedGroupView = editorPane.getIntGroupView(dragPoint);
314: setLocation();
315: }
316:
317: public void mouseMoved(MouseEvent e) {
318: }
319: }
|