source: trunk/org/expeditee/items/Line.java@ 4

Last change on this file since 4 was 4, checked in by davidb, 16 years ago

Starting source code to Expeditee

File size: 21.6 KB
Line 
1package org.expeditee.items;
2
3import java.awt.BasicStroke;
4import java.awt.Color;
5import java.awt.Dimension;
6import java.awt.Graphics2D;
7import java.awt.Point;
8import java.awt.Polygon;
9import java.awt.Rectangle;
10import java.awt.Shape;
11import java.awt.Stroke;
12import java.awt.geom.AffineTransform;
13import java.util.ArrayList;
14import java.util.List;
15
16/**
17 * Implements a line that is drawn on the screen. A line is represented as two
18 * Items that share a common Line ID.
19 *
20 * @author jdm18
21 *
22 */
23public class Line extends Item {
24
25 private static final int AUTO_ARROWHEAD_LENGTH = -1;
26
27 private static final double DEFAULT_ARROWHEAD_RATIO = 0.5;
28
29 private static final int ARROW_HEAD_TO_LENGTH_RATIO = 8;
30
31 private static final int MINIMUM_ARROW_HEAD_LENGTH = 0;
32
33 public static final Float DEFAULT_THICKNESS = 2f;
34
35 public static final Float MINIMUM_THICKNESS = 1f;
36
37 private Item _start;
38
39 private Item _end;
40
41 // old point locations, used for clearing
42 private Point _startOffset = new Point(0, 0);
43
44 private Point _endOffset = new Point(0, 0);
45
46 // indicates which end the arrowhead should be drawn at
47 private Polygon _poly = null;
48
49 private float _thickness = -1;
50
51 private boolean _isCircle = false;
52
53 // brush strokes used for painting this line and highlighting
54 private Stroke _lineStroke = new BasicStroke(DEFAULT_THICKNESS,
55 BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
56
57 // private Stroke _highlightStroke = new BasicStroke (1f + /*GRAVITY +
58 // (GRAVITY * (1 / */(2 *GRAVITY)/*))*/, BasicStroke.CAP_BUTT,
59 // BasicStroke.JOIN_ROUND);
60
61 /**
62 * Constructs a new Line with the given start and end point and Item ID.
63 *
64 * @param start
65 * The starting Point of this Line.
66 * @param end
67 * The end Point of this Line.
68 * @param id
69 * The Item ID of this Line.
70 */
71 public Line(Item start, Item end, int id) {
72 super();
73 setID(id);
74 _start = start;
75 _end = end;
76
77 // update the two end points to add this line
78 _start.addLine(this);
79 _end.addLine(this);
80
81 // initialise the line size
82 float thick;
83 if (_start instanceof Dot)
84 thick = ((Dot) _start).getThickness();
85 else
86 thick = _start.getSize();
87
88 if (_end instanceof Dot)
89 thick += ((Dot) _end).getThickness();
90 else
91 thick += _end.getSize();
92
93 setLinePattern(_start.getLinePattern());
94 // Set the thickness to be half the value of the end points
95 setThickness(thick / 2.0f);
96 }
97
98 /**
99 * Returns the Dot at the start of this Line.
100 *
101 * @return The Dot that is the start of this line.
102 */
103 public Item getStartItem() {
104 return _start;
105 }
106
107 /**
108 * Returns the Dot that is the end of this Line.
109 *
110 * @return The Dot that is the end of this line.
111 */
112 public Item getEndItem() {
113 return _end;
114 }
115
116 /**
117 * Returns the Dot at the opposite end to the Dot given. If the given Dot is
118 * not part of this line, null is returned.
119 *
120 * @param fromThis
121 * The Dot at the opposite end than this Dot is returned
122 * @return The Dot at the opposite end of this Line to the given Dot, or
123 * Null if the given Dot is not on this Line.
124 */
125 public Item getOppositeEnd(Item fromThis) {
126 if (_start == fromThis)
127 return _end;
128
129 if (_end == fromThis)
130 return _start;
131
132 return null;
133 }
134
135 /**
136 * Replaces either the start or end point of this Line with the given Dot.
137 * This is used when merging two Dots.
138 *
139 * @param replace
140 * Either the start or end Dot of this Line indicating which is
141 * to be replaced.
142 * @param with
143 * The Dot to replace the start or end Dot with.
144 */
145 public void replaceEnd(Item replace, Item with) {
146 if (_start == replace)
147 setStartItem(with);
148 else
149 setEndItem(with);
150 }
151
152 public void setStartItem(Item start) {
153 if (start != null) {
154 _start.removeLine(this);
155
156 if (!(start instanceof Dot)) {
157 _startOffset.x = _start.getX() - start.getX();
158 _startOffset.y = _start.getY() - start.getY();
159 } else {
160 _startOffset.x = 0;
161 _startOffset.y = 0;
162 }
163
164 _start = start;
165 _start.addLine(this);
166 updatePolygon();
167 }
168 }
169
170 public void setEndItem(Item end) {
171 if (end != null) {
172 _end.removeLine(this);
173
174 if (!(end instanceof Dot)) {
175 _endOffset.x = _end.getX() - end.getX();
176 _endOffset.y = _end.getY() - end.getY();
177 } else {
178 _endOffset.x = 0;
179 _endOffset.y = 0;
180 }
181
182 _end = end;
183 _end.addLine(this);
184 updatePolygon();
185 }
186 }
187
188 /**
189 * Returns the Y value of the start Dot of this Line. To determine the end
190 * Dot Y value use getEndDot().getY()
191 *
192 * @return The Y value of the starting Dot of this Line.
193 * @see #getStartDot()
194 * @see #getEndDot()
195 */
196 public int getY() {
197 return _start.getY();
198 }
199
200 /**
201 * Returns the X value of the start Dot of this Line. To determine the end
202 * Dot X value use getEndDot().getX()
203 *
204 * @return The X value of the starting Dot of this Line.
205 * @see #getStartDot()
206 * @see #getEndDot()
207 */
208 public int getX() {
209 // return 0;
210 return _start.getX();
211 }
212
213 public void setX(int x) {
214 }
215
216 public void setY(int y) {
217 }
218
219 @Override
220 public void setPosition(int x, int y) {
221 }
222
223 @Override
224 public String getLink() {
225 return null;
226 }
227
228 private void paintCircle(Graphics2D g, Item end) {
229 int distance = (int) Math.sqrt(Math.pow(Math.abs(_start.getX()
230 - _end.getX()), 2)
231 + Math.pow(Math.abs(_start.getY() - _end.getY()), 2));
232
233 // Approximation of circle for mouse interaction
234 int points = 20;
235
236 double radians = 0.0;
237 int xPoints[] = new int[points];
238 int yPoints[] = new int[xPoints.length];
239
240 for (int i = 0; i < xPoints.length; i++) {
241 xPoints[i] = (int) (distance * Math.cos(radians));
242 yPoints[i] = (int) (distance * Math.sin(radians));
243 radians += (2.0 * Math.PI) / xPoints.length;
244 }
245
246 _poly = new Polygon(xPoints, yPoints, xPoints.length);
247 _poly.translate(end.getX(), end.getY());
248
249 distance *= 2;
250
251 g.drawOval(end.getX() - (distance / 2), end.getY() - (distance / 2),
252 distance, distance);
253 // Arc version, same result but allows for portions of the circle to be
254 // drawn
255 // g.drawArc(end.getX() - (distance / 2), end.getY() - (distance / 2),
256 // distance, distance, 0, 360);
257 }
258
259 public void setLinePattern(int[] pattern) {
260 super.setLinePattern(pattern);
261
262 float thick = getThickness();
263
264 if (thick < 0)
265 thick = DEFAULT_THICKNESS;
266
267 if (pattern != null) {
268 float[] dash = new float[pattern.length];
269 for (int i = 0; i < pattern.length; i++)
270 dash[i] = (float) pattern[i];
271 _lineStroke = new BasicStroke(Math.max(thick, MINIMUM_THICKNESS),
272 BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10f, dash,
273 0.0f);
274 } else
275 _lineStroke = new BasicStroke(Math.max(thick, MINIMUM_THICKNESS),
276 BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
277
278 if (_start.getLinePattern() != pattern)
279 _start.setLinePattern(pattern);
280
281 if (_end.getLinePattern() != pattern)
282 _end.setLinePattern(pattern);
283 }
284
285 @Override
286 public void paint(Graphics2D g) {
287 g.setColor(getPaintColor());
288
289 if (_start instanceof Text && ((Text) _start).startsWith("@c")) {
290 g.setStroke(_lineStroke);
291 paintCircle(g, _end);
292 _isCircle = true;
293 } else if (_end instanceof Text && ((Text) _end).startsWith("@c")) {
294 g.setStroke(_lineStroke);
295 paintCircle(g, _start);
296 _isCircle = true;
297 } else {
298 // paint the arrowhead (if necessary)
299 g.setStroke(new BasicStroke(getThickness(), BasicStroke.CAP_BUTT,
300 BasicStroke.JOIN_MITER));
301
302 if (_start.isFloating() && !_end.isFloating()) {
303 paintArrow(g, _start, _startOffset, _endOffset);
304 } else if (!_start.isFloating() && _end.isFloating()) {
305 paintArrow(g, _end, _endOffset, _startOffset);
306 } else {
307 paintArrow(g, _start, _startOffset, _endOffset);
308 paintArrow(g, _end, _endOffset, _startOffset);
309 }
310
311 g.setStroke(_lineStroke);
312 g.drawLine(_start.getX() + _startOffset.x, _start.getY()
313 + _startOffset.y, _end.getX() + _endOffset.x, _end.getY()
314 + _endOffset.y);
315
316 _isCircle = false;
317 }
318
319 // update the highlight shape
320 // java.awt.geom.Line2D.Float shape = new
321 // java.awt.geom.Line2D.Float(_startx, _starty, _endx, _endy);
322 // _shape = _highlightStroke.createStrokedShape(shape);
323
324 // g.setStroke(norm);
325
326 if (showLineHighlight() && isHighlighted()) {
327 g.setColor(getHighlightColor());
328 ((Graphics2D) g).draw(this.getArea());
329 }
330
331 if (_virtualSpot != null) {
332 _virtualSpot.paint(g);
333 _virtualSpot = null;
334 }
335 }
336
337 /**
338 * Based on code from DeSL (Arrow2D) http://sourceforge.net/projects/desl/
339 */
340 private void paintArrow(Graphics2D g, Item withArrow, Point startOffset,
341 Point endOffset) {
342 // only draw an arrowhead if necessary
343 if (!withArrow.hasVisibleArrow() || withArrow.getLines().size() > 1)
344 return;
345
346 int x0, x1, y0, y1;
347
348 x1 = withArrow.getX() + startOffset.x;
349 y1 = withArrow.getY() + startOffset.y;
350 x0 = getOppositeEnd(withArrow).getX() + endOffset.x;
351 y0 = getOppositeEnd(withArrow).getY() + endOffset.y;
352
353 int arrowLength = withArrow.getArrowheadLength();
354 double arrowRatio = withArrow.getArrowheadRatio();
355
356 // if the arrowhead is 'auto', then one and only one end must be
357 // floating
358 if (arrowLength != AUTO_ARROWHEAD_LENGTH && arrowRatio < 0)
359 return;
360
361 int deltaX = x1 - x0;
362 int deltaY = y1 - y0;
363
364 int length = (int) Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
365
366 if (arrowLength < 0) {
367 arrowLength = length / ARROW_HEAD_TO_LENGTH_RATIO;
368 arrowLength = Math.max(MINIMUM_ARROW_HEAD_LENGTH, arrowLength);
369 withArrow.setArrowhead(null);
370 if (arrowRatio < 0)
371 arrowRatio = DEFAULT_ARROWHEAD_RATIO;
372 }
373
374 // only calculate the arrowhead polygon if necessary
375 if (withArrow.getArrowhead() == null) {
376 Polygon arrowhead = new Polygon();
377 arrowhead.addPoint((int) x0, (int) y0);
378 arrowhead.addPoint((int) x0 - arrowLength,
379 (int) (y0 - (arrowLength * arrowRatio)));
380 arrowhead.addPoint((int) x0, (int) y0);
381 arrowhead.addPoint((int) x0 - arrowLength,
382 (int) (y0 + (arrowLength * arrowRatio)));
383 withArrow.setArrowhead(arrowhead);
384 }
385
386 Polygon arrowhead = withArrow.getArrowhead();
387 double rad = calcAngle((float) x0, (float) y0, (float) x1, (float) y1);
388 arrowhead.translate((x0 + length) - arrowhead.xpoints[0], y0
389 - arrowhead.ypoints[0]);
390 AffineTransform tx = AffineTransform.getRotateInstance(rad, x0, y0);
391 g.draw(tx.createTransformedShape((Shape) arrowhead));
392 }
393
394 /**
395 * Calcuates the angle of rotation (in radians) of the arrowhead Based on
396 * code from DeSL (Arrow2D) http://sourceforge.net/projects/desl/
397 */
398 private double calcAngle(float x1, float y1, float x2, float y2) {
399 double rad = 0.0d;
400 float dx = x2 - x1;
401 float dy = y2 - y1;
402
403 if (dx == 0.0) {
404 if (dy == 0.0) {
405 rad = 0.0;
406 } else if (dy > 0.0) {
407 rad = Math.PI / 2.0;
408 } else {
409 rad = Math.PI * 3.0 / 2.0;
410 }
411 } else if (dy == 0.0) {
412 if (dx > 0.0) {
413 rad = 0.0;
414 } else {
415 rad = Math.PI;
416 }
417 } else {
418 if (dx < 0.0) {
419 rad = Math.atan(dy / dx) + Math.PI;
420 } else if (dy < 0.0) {
421 rad = Math.atan(dy / dx) + (2 * Math.PI);
422 } else {
423 rad = Math.atan(dy / dx);
424 }
425 }
426
427 return rad;
428 }
429
430 @Override
431 public Polygon getPolygon() {
432 if (_poly == null)
433 updatePolygon();
434
435 return _poly;
436 }
437
438 @Override
439 public Line copy() {
440 Item s = _start.copy();
441 Item e = _end.copy();
442
443 Line temp = new Line(s, e, getID());
444
445 Item.DuplicateItem(this, temp);
446
447 temp.setLinePattern(getLinePattern());
448 temp.setThickness(getThickness());
449
450 temp.setArrow(getArrowheadLength(), getArrowheadRatio());
451
452 return temp;
453 }
454
455 @Override
456 public int showHighlight(boolean val) {
457 super.showHighlight(val);
458
459 return Item.UNCHANGED_CURSOR;
460 }
461
462 @Override
463 public void setMaxSize(Dimension d) {
464 }
465
466 /**
467 * Sets the Color of this Line and the two Dots at the ends.
468 *
469 * @param c
470 * The Color to paint this Line in.
471 */
472 @Override
473 public void setColor(Color c) {
474 super.setColor(c);
475
476 if (_start.getColor() != c)
477 _start.setColor(c);
478
479 if (_end.getColor() != c)
480 _end.setColor(c);
481 }
482
483 @Override
484 public int getSize() {
485 return _start.getSize();
486 }
487
488 @Override
489 public void setSize(int size) {
490 }
491
492 @Override
493 public void setThickness(float thick) {
494 _thickness = thick;
495
496 if (thick < 0)
497 thick = DEFAULT_THICKNESS;
498
499 if (_start instanceof Dot) {
500 Dot start = (Dot) _start;
501 if (start.getThickness() != thick)
502 start.setThickness(thick);
503 }
504
505 if (_end instanceof Dot) {
506 Dot end = (Dot) _end;
507 if (end.getThickness() != thick)
508 end.setThickness(thick);
509 }
510
511 int[] pattern = _start.getLinePattern();
512 if (pattern == null)
513 pattern = _end.getLinePattern();
514
515 if (pattern != null) {
516 float[] dash = new float[pattern.length];
517 for (int i = 0; i < pattern.length; i++)
518 dash[i] = (float) pattern[i];
519 _lineStroke = new BasicStroke(Math.max(thick, MINIMUM_THICKNESS),
520 BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10f, dash,
521 0.0f);
522 } else
523 _lineStroke = new BasicStroke(Math.max(thick, MINIMUM_THICKNESS),
524 BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
525 }
526
527 @Override
528 public float getThickness() {
529 return _thickness;
530 }
531
532 @Override
533 public void setAnnotation(boolean val) {
534 }
535
536 @Override
537 public boolean isAnnotation() {
538 return false;
539 }
540
541 /**
542 * Fixes the length of the arrowhead on the end of the line.
543 */
544 public void fixArrowheadLength() {
545 if (_end.getArrowheadLength() == AUTO_ARROWHEAD_LENGTH) {
546 fixArrowheadLength(_end);
547 }
548 }
549
550 public void autoArrowheadLength() {
551 _end.setArrowheadLength(AUTO_ARROWHEAD_LENGTH);
552 _end.setArrowheadRatio(DEFAULT_ARROWHEAD_RATIO);
553 }
554
555 public void fixArrowheadLength(Item arrow) {
556 // if the arrow isnt there turn it on!
557 int x0, x1, y0, y1;
558
559 x1 = arrow.getX();
560 y1 = arrow.getY();
561 x0 = getOppositeEnd(arrow).getX();
562 y0 = getOppositeEnd(arrow).getY();
563
564 int deltaX = x1 - x0;
565 int deltaY = y1 - y0;
566
567 int length = (int) Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
568 length /= ARROW_HEAD_TO_LENGTH_RATIO;
569 arrow.setArrowheadLength(Math.max(MINIMUM_ARROW_HEAD_LENGTH, length));
570 }
571
572 public void toggleArrow() {
573 Item arrow;
574 if (_start.isFloating() && !_end.isFloating())
575 arrow = _start;
576 else if (_end.isFloating() && !_start.isFloating())
577 arrow = _end;
578 else
579 return;
580
581 // if there already an arrow, turn it off
582 if (arrow.getArrowheadLength() != 0 && arrow.getArrowheadRatio() > 0) {
583 arrow.setArrowheadLength(0);
584 return;
585 }
586
587 fixArrowheadLength(arrow);
588 }
589
590 private static int[] LinePatterns = new int[] { 0, 10, 20 };
591
592 /**
593 * The rotates through a wheel of dashed lines.
594 *
595 * @param amount
596 * number of rotations around the wheel to toggle by.
597 */
598 public void toggleDashed(int amount) {
599 // find the index of the current line pattern
600 int[] currentPattern = getLinePattern();
601
602 // Find the current pattern and move to the next pattern in the wheel
603 for (int i = 0; i < LinePatterns.length; i++) {
604 if (currentPattern == null || currentPattern[0] == LinePatterns[i]) {
605 i += LinePatterns.length + amount;
606 i %= LinePatterns.length;
607
608 // if we are at the start of the wheel make it 'null' (solid
609 // line)
610 if (i == 0) {
611 setLinePattern(null);
612 } else {
613 setLinePattern(new int[] { LinePatterns[i], LinePatterns[i] });
614 }
615 return;
616 }
617 }
618 }
619
620 private static double[] ArrowHeadRatios = new double[] { 0.25, 0.5, 1.0 };
621
622 /**
623 * This will toggle the arrow head between the various types of UML arrow
624 * heads.
625 *
626 * @param amount
627 */
628 public void toggleArrowHeadRatio(int amount) {
629 Item arrow = null;
630 if (_start.isFloating() && !_end.isFloating())
631 arrow = _start;
632 else if (_end.isFloating() && !_start.isFloating())
633 arrow = _end;
634 else
635 return;
636
637 // find the index of the current line pattern
638 double currentRatio = arrow.getArrowheadRatio();
639
640 // Find the current pattern and move to the next pattern in the wheel
641 for (int i = 0; i < ArrowHeadRatios.length; i++) {
642 if (currentRatio - ArrowHeadRatios[i] < 0.001) {
643 i += ArrowHeadRatios.length + amount;
644 i %= ArrowHeadRatios.length;
645 arrow.setArrowheadRatio(ArrowHeadRatios[i]);
646 return;
647 }
648 }
649 }
650
651 private static int[] ArrowHeadLength = new int[] { /* AUTO_ARROWHEAD_LENGTH, */
652 0, 20, 40, 80 };
653
654 /**
655 * Changes the length of the arrow head. In the future this may toggle the
656 * arrow head between the various types of UML arrow heads.
657 *
658 * @param amount
659 */
660 public void toggleArrowHeadLength(int amount) {
661 Item arrow = null;
662 if (_start.isFloating() && !_end.isFloating())
663 arrow = _start;
664 else if (_end.isFloating() && !_start.isFloating())
665 arrow = _end;
666 else
667 return;
668
669 // find the index of the current line pattern
670 int currentLength = arrow.getArrowheadLength();
671
672 // Find the current pattern and move to the next pattern in the wheel
673 for (int i = 0; i < ArrowHeadLength.length; i++) {
674 if (currentLength <= ArrowHeadLength[i]) {
675 i += ArrowHeadLength.length + amount;
676 i %= ArrowHeadLength.length;
677 arrow.setArrowheadLength(ArrowHeadLength[i]);
678 return;
679 }
680 }
681 }
682
683 private Dot _virtualSpot = null;
684
685 public void showVirtualSpot(Dot orig, int mouseX, int mouseY) {
686 if (orig.getLines().size() != 1)
687 return;
688
689 // lines that are in 'connected' mode, also cannot be attached
690 if (orig.getLines().get(0).getOppositeEnd(orig).isFloating())
691 return;
692
693 Dot spot = orig.copy();
694 spot.setThickness(Math.max(this.getThickness(), 5));
695 if (this.getColor() != Color.RED)
696 spot.setColor(Color.RED);
697 else
698 spot.setColor(Color.BLUE);
699
700 // calculate nearest point on line from spot
701 double slope1;
702 double slope2;
703 double x, y;
704
705 slope1 = (_start.getY() - _end.getY() * 1.0)
706 / (_start.getX() - _end.getX());
707 slope2 = -1 / slope1;
708
709 // if the line is horizontal
710 if (slope1 == 0) {
711 x = spot.getX();
712 y = _start.getY();
713 // if the line is vertical
714 } else if (slope2 == 0) {
715 x = _start.getX();
716 y = spot.getY();
717 // otherwise, the line is sloped
718 } else {
719 x = (-1 * slope2 * spot.getX() + spot.getY() - _start.getY() + slope1
720 * _start.getX())
721 / (slope1 - slope2);
722 y = slope1 * (x - _start.getX()) + _start.getY();
723 }
724
725 // position spot on the line
726 spot.setPosition((int) x, (int) y);
727 _virtualSpot = spot;
728 }
729
730 @Override
731 public Item merge(Item merger, int mouseX, int mouseY) {
732 if (!(merger instanceof Dot))
733 return merger;
734
735 Dot spot = (Dot) merger;
736
737 // dots with multiple lines cannot be attached, nor can dots with no
738 // lines
739 if (spot.getLines().size() != 1)
740 return merger;
741
742 // lines that are in 'connected' mode, also cannot be attached
743 if (spot.getLines().get(0).getOppositeEnd(spot).isFloating())
744 return merger;
745
746 if (spot.getConstraints() != null)
747 spot.getConstraints().clear();
748
749 if (_end.getConstraints() != null)
750 _end.getConstraints().clear();
751
752 if (_start.getConstraints() != null)
753 _start.getConstraints().clear();
754
755 // calculate nearest point on line from spot
756 double slope1;
757 double slope2;
758 double x, y;
759
760 slope1 = (_start.getY() - _end.getY() * 1.0)
761 / (_start.getX() - _end.getX());
762 slope2 = -1 / slope1;
763
764 // if the line is horizontal
765 if (slope1 == 0) {
766 x = merger.getX();
767 y = _start.getY();
768 // if the line is vertical
769 } else if (slope2 == 0) {
770 x = _start.getX();
771 y = merger.getY();
772 // otherwise, the line is sloped
773 } else {
774 x = (-1 * slope2 * spot.getX() + spot.getY() - _start.getY() + slope1
775 * _start.getX())
776 / (slope1 - slope2);
777 y = slope1 * (x - _start.getX()) + _start.getY();
778 }
779
780 // position spot on the line
781 spot.setPosition((int) x, (int) y);
782
783 Line temp = copy();
784
785 temp.setID(-1);
786 temp.setEndItem(_end);
787 temp.setStartItem(spot);
788
789 setEndItem(spot);
790
791 // if(_arrowEnd == spot)
792 // setArrow(-1,-1);
793
794 return spot;
795 }
796
797 @Override
798 public List<Item> getConnected() {
799 return getAllConnected();
800 }
801
802 public List<Item> getAllConnected() {
803 ArrayList<Item> list = new ArrayList<Item>();
804 addAllConnected(list);
805 return list;
806 }
807
808 public void addAllConnected(List<Item> connected) {
809 if (!connected.contains(this))
810 connected.add(this);
811
812 if (!connected.contains(_end))
813 _end.addAllConnected(connected);
814
815 if (!connected.contains(_start))
816 _start.addAllConnected(connected);
817 }
818
819 @Override
820 public boolean equals(Object o) {
821 if (!(o instanceof Line))
822 return false;
823
824 return ((Item) o).getID() == getID();
825 }
826
827 @Override
828 public void setAction(List<String> actions) {
829 }
830
831 @Override
832 public List<String> getAction() {
833 return null;
834 }
835
836 public String getLineEnds() {
837 return _start.getID() + " " + _end.getID();
838 }
839
840 public int getLineType() {
841 return 1;
842 }
843
844 @Override
845 protected void updatePolygon() {
846 if (_isCircle) {
847
848 }
849
850 _poly = new Polygon();
851
852 Rectangle one;
853 Rectangle two;
854
855 /**
856 * TODO: Fake dots seems inefficient, Fix it.
857 */
858
859 // line goes from left->right, one->two
860 if (_start.getX() <= _end.getX()) {
861 /*
862 * one = _start.getPolygon().getBounds(); two =
863 * _end.getPolygon().getBounds();
864 */
865
866 Dot s = new Dot(_start.getX(), _start.getY(), -1);
867 Dot e = new Dot(_end.getX(), _end.getY(), -1);
868
869 one = s.getPolygon().getBounds();
870 two = e.getPolygon().getBounds();
871 } else {
872 Dot s = new Dot(_start.getX(), _start.getY(), -1);
873 Dot e = new Dot(_end.getX(), _end.getY(), -1);
874
875 one = e.getPolygon().getBounds();
876 two = s.getPolygon().getBounds();
877 /*
878 * one = _end.getPolygon().getBounds(); two =
879 * _start.getPolygon().getBounds();
880 */
881 }
882
883 // if one is above two
884 if (one.getY() < two.getY()) {
885 _poly.addPoint((int) one.getMaxX(), (int) one.getMinY());
886 _poly.addPoint((int) two.getMaxX(), (int) two.getMinY());
887 _poly.addPoint((int) two.getMinX(), (int) two.getMaxY());
888 _poly.addPoint((int) one.getMinX(), (int) one.getMaxY());
889 // if one is below two
890 } else {
891 _poly.addPoint((int) one.getMinX(), (int) one.getMinY());
892 _poly.addPoint((int) two.getMinX(), (int) two.getMinY());
893 _poly.addPoint((int) two.getMaxX(), (int) two.getMaxY());
894 _poly.addPoint((int) one.getMaxX(), (int) one.getMaxY());
895 }
896 }
897}
Note: See TracBrowser for help on using the repository browser.