source: trunk/src/org/expeditee/items/Item.java@ 50

Last change on this file since 50 was 50, checked in by ra33, 16 years ago

A whole day of big changes.
Adding the ability to have Text at the end of Lines.
Also a lot of refactoring to improve the quality of code relating to constraints and lines

File size: 36.4 KB
Line 
1package org.expeditee.items;
2
3import java.awt.Color;
4import java.awt.Cursor;
5import java.awt.Dimension;
6import java.awt.Graphics2D;
7import java.awt.Point;
8import java.awt.Polygon;
9import java.awt.Rectangle;
10import java.awt.geom.Area;
11import java.util.ArrayList;
12import java.util.ConcurrentModificationException;
13import java.util.LinkedList;
14import java.util.List;
15
16import org.expeditee.actions.Actions;
17import org.expeditee.actions.Simple;
18import org.expeditee.gui.DisplayIO;
19import org.expeditee.gui.Frame;
20import org.expeditee.gui.FrameGraphics;
21import org.expeditee.gui.FrameIO;
22import org.expeditee.gui.FrameUtils;
23import org.expeditee.io.Conversion;
24import org.expeditee.io.Logger;
25import org.expeditee.simple.Context;
26import org.expeditee.stats.AgentStats;
27
28/**
29 * Represents everything that can be drawn on the screen (text, lines, dots,
30 * images). Each specific type is a subclass of Item.
31 *
32 * @author jdm18
33 *
34 */
35public abstract class Item implements Comparable<Item>, Runnable {
36
37 // contains all dots (including this one) that form an enclosure
38 // if this dot is part of an enclosing shape
39 private List<Item> _enclosure = null;
40
41 public static int PERMISSION_NONE = 0;
42
43 public static int PERMISSION_FOLLOW_LINKS = 1;
44
45 public static int PERMISSION_COPY = 2;
46
47 public static int PERMISSION_TDFC = 3;
48
49 public static int PERMISSION_FULL = 4;
50
51 public static final int NEAR_DISTANCE = 15;
52
53 /**
54 * The default Color to draw highlighting in
55 */
56 public static final int DEFAULT_HIGHLIGHT_THICKNESS = 2;
57
58 public static final Color DEFAULT_HIGHLIGHT = Color.RED;
59
60 public static final Color DEPRESSED_HIGHLIGHT = Color.GREEN;
61
62 public static final Color DISCONNECT_HIGHLIGHT = Color.BLUE;
63
64 public static final Color LINK_COLOR = Color.BLACK;
65
66 public static final Color ACTION_COLOR = Color.BLACK;
67
68 public static final Color LINK_ACTION_COLOR = Color.RED;
69
70 public static final Color DEFAULT_FOREGROUND = Color.BLACK;
71
72 public static final Color DEFAULT_BACKGROUND = org.expeditee.gui.DisplayIO.DEFAULT_BACKGROUND;
73
74 /**
75 * The number of pixels highlighting should extend around Items.
76 */
77 public static final int XGRAVITY = 3;
78
79 public static final int MARGIN_RIGHT = 10;
80
81 public static final int MARGIN_LEFT = 20;
82
83 protected static final double DEFAULT_ARROWHEAD_RATIO = 0.5;
84
85 public static final Color GREEN = Color.GREEN.darker();
86
87 /**
88 * The Colors cycled through when using function keys to set the Color of
89 * this Item.
90 */
91 public static Color[] COLOR_WHEEL = { Color.BLACK, Color.RED, Color.BLUE,
92 Item.GREEN, Color.MAGENTA, Color.YELLOW.darker(),
93 DisplayIO.DEFAULT_BACKGROUND };
94
95 public static Color[] FILL_COLOR_WHEEL = { Color.BLACK,
96 new Color(255, 150, 150), new Color(150, 150, 255),
97 new Color(150, 255, 150), new Color(255, 150, 255),
98 new Color(255, 255, 100), DisplayIO.DEFAULT_BACKGROUND };
99
100 public static final int UNCHANGED_CURSOR = -100;
101
102 public static final int DEFAULT_CURSOR = Cursor.DEFAULT_CURSOR;
103
104 public static final int HIDDEN_CURSOR = Cursor.CUSTOM_CURSOR;
105
106 public static final int TEXT_CURSOR = Cursor.TEXT_CURSOR;
107
108 public static final int CROP_CURSOR = Cursor.CROSSHAIR_CURSOR;
109
110 public static final int JUSTIFICATION_NONE = -1;
111
112 // private boolean _isValidLink = true;
113
114 public static final int JUSTIFICATION_FULL = 0;
115
116 public static final int JUSTIFICATION_CENTER = 1;
117
118 public static final int JUSTIFICATION_RIGHT = 2;
119
120 public static final int JUSTIFICATION_LEFT = 3;
121
122 public static final int POINTTYPE_SQUARE = -1;
123
124 public static final int POINTTYPE_CIRCLE = 0;
125
126 public static void DuplicateItem(Item source, Item dest) {
127 dest.setX(source.getX());
128 dest.setY(source.getY());
129
130 dest.setAction(source.getAction());
131 dest.setActionCursorEnter(source.getActionCursorEnter());
132 dest.setActionCursorLeave(source.getActionCursorLeave());
133 dest.setActionEnterFrame(source.getActionEnterFrame());
134 dest.setActionLeaveFrame(source.getActionLeaveFrame());
135 dest.setActionMark(source.getActionMark());
136 dest.setAnnotation(source.isAnnotation());
137
138 dest.setBackgroundColor(source.getBackgroundColor());
139 dest.setBottomShadowColor(source.getBottomShadowColor());
140 dest.setColor(source.getColor());
141
142 dest.setData(source.getData());
143 dest.setFillColor(source.getFillColor());
144 dest.setFillPattern(source.getFillPattern());
145
146 dest.setHighlight(source.getHighlight());
147 dest.setLink(source.getLink());
148 dest.setLinkFrameset(source.getLinkFrameset());
149 dest.setLinkMark(source.getLinkMark());
150 dest.setLinkTemplate(source.getLinkTemplate());
151
152 dest.setMaxSize(source.getMaxSize());
153 dest.setOffset(source.getOffset());
154 dest.setOwner(source.getOwner());
155 dest.setThickness(source.getThickness());
156 dest.setSize(source.getSize());
157 dest.setTopShadowColor(source.getTopShadowColor());
158 dest.setLinePattern(source.getLinePattern());
159
160 dest.setFloating(source.isFloating());
161 dest.setArrow(source.getArrowheadLength(), source.getArrowheadRatio());
162
163 dest.setParent(source.getParent());
164 // Add the copied item to the frame
165 if (source.getParent() != null) {
166 dest.setID(source.getParent().getNextItemID());
167 } else {
168 dest.setID(source.getID());
169 }
170 }
171
172 public static int getGravity() {
173 return org.expeditee.gui.UserSettings.Gravity;
174 }
175
176 public static boolean showLineHighlight() {
177 return org.expeditee.gui.UserSettings.LineHighlight;
178 }
179
180 public enum SelectedMode {
181 None, Enclosed, Connected, Disconnect, Normal
182 }
183
184 public void setSelectedMode(SelectedMode mode) {
185 setSelectedMode(mode, DEFAULT_HIGHLIGHT);
186 }
187
188 protected SelectedMode _mode = SelectedMode.None;
189
190 private Point _offset = new Point(0, 0);
191
192 private int _x;
193
194 private int _y;
195
196 private int _id;
197
198 private String _creationDate = null;
199
200 private boolean _linkMark = true;
201
202 private boolean _actionMark = true;
203
204 private boolean _highlight = true;
205
206 private Dimension _maxSize = null;
207
208 private String _owner = null;
209
210 private String _link = null;
211
212 private StringBuffer _data = new StringBuffer();
213
214 private List<String> _actionCursorEnter = null;
215
216 private List<String> _actionCursorLeave = null;
217
218 private List<String> _actionEnterFrame = null;
219
220 private List<String> _actionLeaveFrame = null;
221
222 public int Permission = PERMISSION_FULL;
223
224 private Color _colorFill = null;
225
226 private Color _color = null;
227
228 private Color _highlightColor = DEFAULT_HIGHLIGHT;
229
230 private Color _colorBackground = null;
231
232 private Color _colorTopShadow = null;
233
234 private Color _colorBottomShadow = null;
235
236 // the link\action circle
237 private Polygon _circle = null;
238
239 // the invalid link cross
240 private Polygon _circleCross = null;
241
242 private Frame _parent = null;
243
244 protected int _highlightThickness = 2;
245
246 // arrowhead parameters
247 private int _arrowheadLength = 0;
248
249 private double _arrowheadRatio = DEFAULT_ARROWHEAD_RATIO;
250
251 private Polygon _arrowhead = null;
252
253 // the list of lines that this point is part of.
254 private List<Line> _lines = new ArrayList<Line>();
255
256 private int[] _linePattern = null;
257
258 private boolean _floating = false;
259
260 // list of points constrained with this point
261 private List<Constraint> _constraints = new ArrayList<Constraint>();
262
263 private LinkedList<String> _actions = null;
264
265 private String _link_frameset = null;
266
267 private String _link_template = null;
268
269 private String _fillPattern = null;
270
271 private boolean _visible = true;
272
273 private SelectedMode _lastMode = SelectedMode.None;
274
275 private float _thickness = -1.0F;
276
277 protected Item() {
278 _creationDate = Logger.EasyDateFormat("ddMMMyyyy:HHmm");
279 }
280
281 /**
282 * Adds an action to this Item.
283 *
284 * @param action
285 * The KMS action language to add to this Item
286 */
287 public void addAction(String action) {
288 if (action == null || action.equals("")) {
289 return;
290 }
291
292 if (_actions == null)
293 _actions = new LinkedList<String>();
294 _actions.add(action);
295 }
296
297 public void addAllConnected(List<Item> connected) {
298 if (!connected.contains(this))
299 connected.add(this);
300
301 for (Line line : getLines()) {
302 if (!connected.contains(line))
303 line.addAllConnected(connected);
304 }
305 }
306
307 /**
308 * Adds the given Constraint to this Dot
309 *
310 * @param c
311 * The Constraint to set this Dot as a member of.
312 */
313 public void addConstraint(Constraint c) {
314 // do not add duplicate constraint
315 if (_constraints.contains(c))
316 return;
317
318 _constraints.add(c);
319 }
320
321 /**
322 * Adds a given line to the list of lines that this Point is an end for.
323 *
324 * @param line
325 * The Line that this Point is an end of.
326 */
327 public void addLine(Line line) {
328 if (_lines.contains(line)) {
329 return;
330 }
331
332 _lines.add(line);
333 }
334
335 /**
336 * Items are sorted by their Y coordinate on the screen.
337 *
338 * @param i
339 * The Item to compare this Item to
340 * @return a negative integer, zero, or a positive integer as this object is
341 * less than, equal to, or greater than the specified object.
342 */
343 public int compareTo(Item i) {
344 return getY() - i.getY();
345 }
346
347 /**
348 * Every Item has an area around it defined by a Shape (typically a
349 * rectangle), this method returns true if the given x,y pair lies within
350 * the area and false otherwise.
351 *
352 * @param x
353 * The x coordinate to check
354 * @param y
355 * The y coordinate to check
356 * @return True if the Shape around this Item contains the given x,y pair,
357 * false otherwise.
358 */
359 public boolean contains(int x, int y) {
360 return getPolygon().contains(x, y);
361 }
362
363 /**
364 * Returns a deep copy of this Item, note: it is up to the receiver to
365 * change the Item ID etc as necessary.
366 *
367 * @return A deep copy of this Item.
368 */
369 public abstract Item copy();
370
371 public void delete() {
372 setVisible(false);
373 }
374
375 public boolean equals(Object o) {
376 if (o instanceof Item) {
377 Item i = (Item) o;
378 return i.getID() == getID()
379 && ((i.getParent() == _parent) || (i.getParent() != null && i
380 .getParent().equals(_parent)));
381
382 } else
383 return false;
384 }
385
386 final public String getAbsoluteLink() {
387 String link = getLink();
388
389 if (link == null)
390 return null;
391 // assert (_parent!= null);
392 if (_parent == null) {
393 // if parent is null it is an item on the message box
394 // so it must already be absolute
395 assert (!FrameIO.isPositiveInteger(link));
396 return link;
397 }
398
399 // if its a relative link then return absolute
400 if (FrameIO.isPositiveInteger(link)) {
401 return _parent.getFramesetName() + Conversion.getFrameNumber(link);
402 }
403 return link;
404 }
405
406 /**
407 * Returns a list of any action code (KMS action language) that is currently
408 * associated with this Item
409 *
410 * @return A List of action code associated with this Item, or null if none
411 * has been assigned.
412 */
413 public List<String> getAction() {
414 return _actions;
415 }
416
417 public List<String> getActionCursorEnter() {
418 return _actionCursorEnter;
419 }
420
421 public List<String> getActionCursorLeave() {
422 return _actionCursorLeave;
423 }
424
425 public List<String> getActionEnterFrame() {
426 return _actionEnterFrame;
427 }
428
429 public List<String> getActionLeaveFrame() {
430 return _actionLeaveFrame;
431 };
432
433 public boolean getActionMark() {
434 return _actionMark;
435 }
436
437 public List<Item> getAllConnected() {
438 List<Item> list = new LinkedList<Item>();
439 addAllConnected(list);
440 return list;
441 }
442
443 public Area getArea() {
444 return new Area(getPolygon());
445 }
446
447 public String getArrow() {
448 if (!hasVisibleArrow())
449 return null;
450
451 String ratio = "" + getArrowheadRatio();
452 if (ratio.length() - ratio.indexOf(".") > 2)
453 ratio = ratio.substring(0, ratio.indexOf(".") + 3);
454
455 return getArrowheadLength() + " " + ratio;
456 }
457
458 public Polygon getArrowhead() {
459 return _arrowhead;
460 }
461
462 public int getArrowheadLength() {
463 return _arrowheadLength;
464 }
465
466 public double getArrowheadRatio() {
467 return _arrowheadRatio;
468 }
469
470 public Color getBackgroundColor() {
471 return _colorBackground;
472 }
473
474 /**
475 * Returns the Color being used to shade the bottom half of this Item's
476 * border. This can be NULL if no Color is being used
477 *
478 * @return The Color displayed on the bottom\right half of this Item's
479 * border.
480 */
481 public Color getBottomShadowColor() {
482 return _colorBottomShadow;
483 }
484
485 /**
486 * Returns the height (in pixels) of this Item's surrounding area.
487 *
488 * @return The height (in pixels) of this Item's surrounding area as
489 * returned by getArea().
490 */
491 public int getBoundsHeight() {
492 return getPolygon().getBounds().height;
493 }
494
495 /**
496 * Returns the width (in pixels) of this Item's surrounding area.
497 *
498 * @return The width (in pixels) of this Item's surrounding area as returned
499 * by getArea().
500 */
501 public int getBoundsWidth() {
502 return getPolygon().getBounds().width;
503 }
504
505 protected Polygon getCircle() {
506 if (_circle == null) {
507 int points = 16;
508
509 double radians = 0.0;
510 int xPoints[] = new int[points];
511 int yPoints[] = new int[xPoints.length];
512
513 for (int i = 0; i < xPoints.length; i++) {
514 // circle looks best if these values are not related to gravity
515 xPoints[i] = (int) (3.5 * Math.cos(radians)) + 6;// (2 *
516 // GRAVITY);
517 yPoints[i] = (int) (3.5 * Math.sin(radians)) + 3;// GRAVITY;
518 radians += (2.0 * Math.PI) / xPoints.length;
519 }
520
521 _circle = new Polygon(xPoints, yPoints, xPoints.length);
522 }
523
524 return _circle;
525 }
526
527 protected Polygon getCircleCross() {
528
529 if (_circleCross == null) {
530 _circleCross = new Polygon();
531
532 Rectangle bounds = getCircle().getBounds();
533 int x1 = (int) bounds.getMinX();
534 int x2 = (int) bounds.getMaxX();
535 int y1 = (int) bounds.getMinY();
536 int y2 = (int) bounds.getMaxY();
537 int midX = ((x2 - x1) / 2) + x1;
538 int midY = ((y2 - y1) / 2) + y1;
539
540 _circleCross.addPoint(x1, y1);
541 _circleCross.addPoint(x2, y2);
542 _circleCross.addPoint(midX, midY);
543 _circleCross.addPoint(x1, y2);
544 _circleCross.addPoint(x2, y1);
545 _circleCross.addPoint(midX, midY);
546 }
547
548 return _circleCross;
549 }
550
551 public Color getColor() {
552 return _color;
553 }
554
555 public List<Item> getConnected() {
556 List<Item> conn = new LinkedList<Item>();
557 conn.add(this);
558
559 conn.addAll(getLines());
560 return conn;
561 }
562
563 public String getConstraintIDs() {
564 if (_constraints == null || _constraints.size() == 0)
565 return null;
566
567 String cons = "";
568
569 for (Constraint c : _constraints)
570 cons += c.getID() + " ";
571
572 return cons.trim();
573 }
574
575 /*
576 * public void setLinkValid(boolean val) { _isValidLink = val; }
577 */
578
579 /**
580 * Returns a List of any Constraints that this Dot is a memeber of.
581 *
582 * @return a List of Constraints that this Dot is a member of.
583 */
584 public List<Constraint> getConstraints() {
585 return _constraints;
586 }
587
588 public String getData() {
589 if (_data != null && _data.length() > 0)
590 return _data.toString();
591 return null;
592 }
593
594 public String getDateCreated() {
595 return _creationDate;
596 }
597
598 public Color getFillColor() {
599 return _colorFill;
600 }
601
602 public String getFillPattern() {
603 return _fillPattern;
604 }
605
606 public String getFirstAction() {
607 if (_actions == null)
608 return null;
609 return _actions.getFirst();
610 }
611
612 public boolean getHighlight() {
613 return _highlight;
614 }
615
616 public Color getHighlightColor() {
617 return _highlightColor;
618 }
619
620 /**
621 * Returns the ID of this Item, which must be unique for the Frame.
622 *
623 * @return The ID of this Item.
624 */
625 public int getID() {
626 return _id;
627 }
628
629 /**
630 * Returns the list of IDs of the Lines that this Dot is an end of.
631 *
632 * @return The list of Line IDs that this point is part of.
633 */
634 public String getLineIDs() {
635 String lineID = null;
636
637 if (_lines.size() > 0) {
638 lineID = "" + _lines.get(0).getID();
639
640 for (int i = 1; i < _lines.size(); i++)
641 lineID += " " + _lines.get(i).getID();
642 }
643
644 return lineID;
645 }
646
647 public int[] getLinePattern() {
648 return _linePattern;
649 }
650
651 /**
652 * Returns a list of Lines where this Dot is an end.
653 *
654 * @return A list of the Lines that this Dot is an end for or null if no
655 * Lines have been added.
656 */
657 public List<Line> getLines() {
658 return _lines;
659 }
660
661 /**
662 * Returns the name of a Frame that this Item links to, or null if this Item
663 * has no link.
664 *
665 * @return The name of a Frame that this Item links to (if any) or null if
666 * this Item does not link to anything.
667 */
668 public String getLink() {
669 return _link;
670 }
671
672 public String getLinkFrameset() {
673 return _link_frameset;
674 }
675
676 public boolean getLinkMark() {
677 return _linkMark;
678 }
679
680 public String getLinkTemplate() {
681 return _link_template;
682 }
683
684 public Dimension getMaxSize() {
685 return _maxSize;
686 }
687
688 public Point getOffset() {
689 return _offset;
690 }
691
692 public String getOwner() {
693 return _owner;
694 }
695
696 public Color getPaintBackgroundColor() {
697 if (_colorBackground == null) {
698 if (getParent() != null && getParent().getBackgroundColor() != null)
699 return getParent().getBackgroundColor();
700
701 return DEFAULT_BACKGROUND;
702 }
703
704 return _colorBackground;
705 }
706
707 /**
708 * Returns the foreground Color of this Item.
709 *
710 * @return The Color of this item (foreground)
711 */
712 public Color getPaintColor() {
713 if (_color == null) {
714 if (getParent() != null)
715 return getParent().getPaintForegroundColor();
716
717 if (DisplayIO.getCurrentFrame() == null)
718 return DEFAULT_FOREGROUND;
719
720 return DisplayIO.getCurrentFrame().getPaintForegroundColor();
721 }
722
723 return _color;
724 }
725
726 protected Color getPaintHighlightColor() {
727 if (getParent() != null
728 && getParent().getPaintBackgroundColor()
729 .equals(_highlightColor))
730 return getParent().getPaintForegroundColor();
731
732 return _highlightColor;
733 }
734
735 public Frame getParent() {
736 return _parent;
737 }
738
739 /**
740 * Returns the Shape that surrounds this Item representing this Item's
741 * 'gravity'.
742 *
743 * @return The Shape (rectangle) surrounding this Item, which represents
744 * this Items 'gravity'.
745 */
746 public abstract Polygon getPolygon();
747
748 public Point getPosition() {
749 return new Point(getX(), getY());
750 }
751
752 /**
753 * Returns the size of this Item. For Text this is the Font size, for Lines
754 * and Dots this is the thickness.
755 *
756 * @return The size of this Item.
757 */
758 public int getSize() {
759 return -1;
760 }
761
762 /**
763 * Returns the Color being used to shade the top half of this Item's border.
764 * This can be NULL if no Color is being used
765 *
766 * @return The Color displayed on the top\left half of this Item's border.
767 */
768 public Color getTopShadowColor() {
769 return _colorTopShadow;
770 }
771
772 public String getTypeAndID() {
773 return "T " + getID();
774 }
775
776 public int getWidth() {
777 return 0;
778 }
779
780 /**
781 * Returns the X coordinate of this Item on the screen
782 *
783 * @return The X coordinate of this Item on the screen
784 */
785 public int getX() {
786 return _x;
787 }
788
789 /**
790 * Returns the Y coordinate of this Item on the screen
791 *
792 * @return The Y coordinate of this Item on the screen
793 */
794 public int getY() {
795 return _y;
796 }
797
798 protected boolean hasVisibleArrow() {
799 return false;
800 }
801
802 /**
803 * Checks if the given Shape intersects with the Shape around this Item.
804 * Note: Both Shape objects should be rectangles for this to work properly.
805 *
806 * @param s
807 * The Shape to check.
808 * @return True if the two Shapes overlap, False otherwise.
809 */
810 public boolean intersects(Polygon p) {
811 if (p == null)
812 return false;
813
814 // return p.getBounds().intersects(getArea().getBounds());
815 Area a = new Area(p);
816
817 a.intersect(this.getArea());
818 return !a.isEmpty();
819 }
820
821 /**
822 * Note: Pictures always return False, as they should be drawn even when no
823 * other annotation Items are.
824 *
825 * @return True if this Item is an annotation, False otherwise.
826 */
827 public abstract boolean isAnnotation();
828
829 public boolean isFloating() {
830 return _floating;
831 }
832
833 public boolean isFrameName() {
834 if (this.getParent() == null
835 || this.getParent().getFrameNameItem() != this)
836 return false;
837 return true;
838 }
839
840 public boolean isFrameTitle() {
841 if (this.getParent() == null || this.getParent().getTitle() != this)
842 return false;
843 return true;
844 }
845
846 /**
847 * Returns True if this Item is currently highlighted.
848 *
849 * @return True if this Item is currently highlighted on the screen, False
850 * otherwise.
851 */
852 public boolean isHighlighted() {
853 return _mode != SelectedMode.None;
854 }
855
856 /**
857 * Tests if the item link is a valid framename, that is, the String must
858 * begin with a character, end with a number with 0 or more letters and
859 * numbers in between. If there is a dot in the framename all the chars
860 * after it must be digits.
861 *
862 * @return True if the given framename is proper, false otherwise.
863 */
864 public boolean isLinkValid() {
865 if (FrameIO.isPositiveInteger(getLink()))
866 return true;
867
868 if (FrameIO.isValidFrameName(getLink()))
869 return true;
870 return false;
871 }
872
873 public boolean isNear(int x, int y) {
874
875 int xLeft = getPolygon().getBounds().x;
876 int yTop = getPolygon().getBounds().y;
877
878 return (x > xLeft - NEAR_DISTANCE && y > yTop - NEAR_DISTANCE
879 && x < xLeft + getBoundsWidth() + NEAR_DISTANCE && y < yTop
880 + getBoundsHeight() + NEAR_DISTANCE);
881 }
882
883 /**
884 * Checks if this item is a frame title.
885 *
886 * @return true if the item is a frame title
887 */
888 /*
889 * public boolean isTitle() { // check if the title has been assigned if
890 * (getID() >= 0 && this instanceof Text) if (getX() < 200 && getY() <
891 * getSize() + system.io.KMSConversion.Y_ADJUST) return true; return false; }
892 */
893
894 public boolean isOldTag() {
895 if (this instanceof Text)
896 if (((Text) this).getText().get(0).toLowerCase().equals("@old"))
897 return true;
898 return false;
899 }
900
901 /**
902 * Merges this Item with the given Item. The merger Item should be left
903 * unchanged after this method. The merger may or may not be the same class
904 * as this Item, exact behaviour depends on the subclass, No-op is allowed.
905 *
906 * @param merger
907 * The Item to merge with
908 * @param mouseX
909 * The X coordinate of the mouse when performing this merge
910 * operation
911 * @param mouseY
912 * The Y coordinate of the mouse when performing this merge
913 * operation
914 * @return any Item that should remain on the cursor
915 */
916 public abstract Item merge(Item merger, int mouseX, int mouseY);
917
918 /**
919 * Displays this item directly on the screen. Note: All Items are
920 * responsible for their own drawing, buffering, etc.
921 *
922 * @param g
923 * The Graphics to draw this Item on.
924 */
925 public abstract void paint(Graphics2D g);
926
927 /**
928 * This method performs all the actions in an items list. If it contains a
929 * link as well the link is used as the source frame for all acitons.
930 */
931 public void performActions() {
932 Frame sourceFrame = null;
933 // if a link exists make it the source frame for this action
934 if (getLink() != null) {
935 sourceFrame = FrameUtils.getFrame(getLink());
936 }
937 // if no link exists or the link is bad then use the
938 // currently displayed frame as the source frame for the
939 // action
940 if (sourceFrame == null) {
941 sourceFrame = DisplayIO.getCurrentFrame();
942 }
943
944 for (String s : getAction()) {
945 Actions.PerformAction(sourceFrame, this, s);
946 }
947 }
948
949 /**
950 * Removes all constraints that this item has.
951 *
952 */
953 public void removeAllConstraints() {
954 while (_constraints.size() > 0) {
955 Constraint c = _constraints.get(0);
956 c.getEnd().removeConstraint(c);
957 c.getStart().removeConstraint(c);
958 }
959 }
960
961 /**
962 * Clears the list of Lines that this Dot is an end of. Note: This only
963 * clears this Dot's list and does not have any affect on the Lines or other
964 * Dots.
965 */
966 public void removeAllLines() {
967 _lines.clear();
968 }
969
970 /**
971 * Removes the given Constraint from the list of constraintss that this Dot
972 * is a part of.
973 *
974 * @param c
975 * The Constraint that this Dot is no longer a part of.
976 */
977 public void removeConstraint(Constraint c) {
978 _constraints.remove(c);
979 }
980
981 /**
982 * Removes the given Line from the list of lines that this Dot is an end
983 * for.
984 *
985 * @param line
986 * The Line that this Dot is no longer an end of.
987 */
988 public void removeLine(Line line) {
989 _lines.remove(line);
990 }
991
992 public void run() {
993 try {
994 AgentStats.reset();
995 FrameGraphics
996 .DisplayMessage("Running SimpleProgram...", Color.BLUE);
997 Simple.RunFrameAndReportError(this, new Context());
998 Simple.ProgramFinished();
999 FrameGraphics.DisplayMessage(AgentStats.getStats(), GREEN);
1000 } catch (ConcurrentModificationException ce) {
1001 ce.printStackTrace();
1002 } catch (Exception e) {
1003 FrameGraphics.LinkedErrorMessage(e.getMessage());
1004 Simple.ProgramFinished();
1005 }
1006 }
1007
1008 /**
1009 * Check if it has a relative link if so make it absolute.
1010 *
1011 */
1012 public void setAbsoluteLink() {
1013 if (_link == null)
1014 return;
1015 // Check if all the characters are digits and hence it is a relative
1016 // link
1017 for (int i = 0; i < _link.length(); i++) {
1018 if (!Character.isDigit(_link.charAt(i)))
1019 return;
1020 }
1021
1022 // Make it an absolute link
1023 String framesetName;
1024
1025 if (_parent == null)
1026 framesetName = DisplayIO.getCurrentFrame().getFramesetName();
1027 else
1028 framesetName = _parent.getFramesetName();
1029
1030 _link = framesetName + _link;
1031 }
1032
1033 /**
1034 * Sets any action code (KMS action language) that should be associated with
1035 * this Item Each entry in the list is one line of code
1036 *
1037 * @param actions
1038 * The lines of code to associate with this Item
1039 */
1040 public void setAction(List<String> actions) {
1041 if (actions == null || actions.size() == 0)
1042 _actions = null;
1043 else
1044 _actions = new LinkedList<String>(actions);
1045 }
1046
1047 public void setActionCursorEnter(List<String> enter) {
1048 _actionCursorEnter = enter;
1049 }
1050
1051 public void setActionCursorLeave(List<String> leave) {
1052 _actionCursorLeave = leave;
1053 }
1054
1055 public void setActionEnterFrame(List<String> enter) {
1056 _actionEnterFrame = enter;
1057 }
1058
1059 public void setActionLeaveFrame(List<String> leave) {
1060 _actionLeaveFrame = leave;
1061 }
1062
1063 public void setActionMark(boolean val) {
1064 _actionMark = val;
1065 }
1066
1067 /**
1068 * Sets whether this Item is an Annotation.
1069 *
1070 * @param val
1071 * True if this Item is an Annotation, False otherwise.
1072 */
1073 public abstract void setAnnotation(boolean val);
1074
1075 /**
1076 * Used to set this Line as an Arrow. If length and ratio are 0, no arrow is
1077 * shown.
1078 *
1079 * @param length
1080 * The how far down the shaft of the line the arrowhead should
1081 * come.
1082 * @param ratio
1083 * The ratio of the arrow's length to its width.
1084 */
1085 public void setArrow(int length, double ratio) {
1086 _arrowheadLength = length;
1087 _arrowheadRatio = ratio;
1088 updateArrowPolygon();
1089 }
1090
1091 public void setArrowhead(Polygon arrow) {
1092 _arrowhead = arrow;
1093 }
1094
1095 public void setArrowheadLength(int length) {
1096 _arrowheadLength = length;
1097 updateArrowPolygon();
1098 }
1099
1100 public void setArrowheadRatio(double ratio) {
1101 _arrowheadRatio = ratio;
1102 updateArrowPolygon();
1103 }
1104
1105 public void setBackgroundColor(Color c) {
1106 _colorBackground = c;
1107 }
1108
1109 /**
1110 * Sets the Color to use on the bottom and right sections of this Item's
1111 * border. If top is NULL, then the Item's background Color will be used.
1112 *
1113 * @param top
1114 * The Color to display in the bottom and right sections of this
1115 * Item's border.
1116 */
1117 public void setBottomShadowColor(Color bottom) {
1118 _colorBottomShadow = bottom;
1119 }
1120
1121 /**
1122 * Sets the foreground Color of this Item to the given Color.
1123 *
1124 * @param c
1125 */
1126 public void setColor(Color c) {
1127 _color = c;
1128 }
1129
1130 public void setConstraintIDs(String IDs) {
1131 }
1132
1133 public void setConstraints(List<Constraint> constraints) {
1134 _constraints = constraints;
1135 }
1136
1137 public void setData(String newData) {
1138 if (newData != null)
1139 _data = new StringBuffer(newData);
1140 else
1141 _data = null;
1142 }
1143
1144 /**
1145 * Sets the created date of this Frame to the given String.
1146 *
1147 * @param date
1148 * The date to use for this Frame.
1149 */
1150 public void setDateCreated(String date) {
1151 _creationDate = date;
1152 }
1153
1154 public void setFillColor(Color c) {
1155 _colorFill = c;
1156
1157 for (Line line : _lines) {
1158 Item other = line.getOppositeEnd(this);
1159 if (other.getFillColor() != c)
1160 other.setFillColor(c);
1161 }
1162 }
1163
1164 public void setFilledHighlight(boolean value) {
1165 }
1166
1167 public void setFillPattern(String patternLink) {
1168 _fillPattern = patternLink;
1169 }
1170
1171 public void setFloating(boolean val) {
1172 _floating = val;
1173 }
1174
1175 public void setHighlight(boolean val) {
1176 _highlight = val;
1177 }
1178
1179 /**
1180 * Sets the ID of this Item to the given Integer. Note: Items with ID's < 0
1181 * are not saved
1182 *
1183 * @param newID
1184 * The new ID to assign this Item.
1185 */
1186 public void setID(int newID) {
1187 _id = newID;
1188 }
1189
1190 /**
1191 * Sets the list of lines that this point is part of (may be set to null).
1192 *
1193 * @param lineID
1194 * A String of line ID numbers separated by spaces.
1195 */
1196 public void setLineIDs(String lineID) {
1197 }
1198
1199 public void setLinePattern(int[] pattern) {
1200 _linePattern = pattern;
1201
1202 for (Line line : getLines())
1203 line.setLinePattern(pattern);
1204 }
1205
1206 public void setLines(List<Line> lines) {
1207 _lines = lines;
1208
1209 for (Line line : lines)
1210 line.setLinePattern(getLinePattern());
1211 }
1212
1213 /**
1214 * Links this item to the given Frame, this may be set to null to remove a
1215 * link.
1216 *
1217 * @param frameName
1218 * The name of the Frame to link this item to.
1219 */
1220 public void setLink(String frameName) {
1221 _link = frameName;
1222 }
1223
1224 public void setLinkFrameset(String frameset) {
1225 _link_frameset = frameset;
1226 }
1227
1228 public void setLinkMark(boolean val) {
1229 _linkMark = val;
1230 }
1231
1232 public void setLinkTemplate(String template) {
1233 _link_template = template;
1234 }
1235
1236 /**
1237 * Sets the maximum coordinates on the screen that this item may occupy.
1238 * This is used by Text items to compute word-wrapping lengths.
1239 *
1240 * @param d
1241 * The Maximum size of the Frame containing this Item.
1242 */
1243 public void setMaxSize(Dimension d) {
1244 if (d != null) {
1245 _maxSize = d;
1246 updatePolygon();
1247 }
1248 }
1249
1250 public void setOffset(int x, int y) {
1251 _offset.setLocation(x, y);
1252 }
1253
1254 public void setOffset(Point p) {
1255 _offset.setLocation(p);
1256 }
1257
1258 public void setOwner(String own) {
1259 _owner = own;
1260 }
1261
1262 public void setParent(Frame frame) {
1263 _parent = frame;
1264 }
1265
1266 /**
1267 * Sets the position of this item on the screen
1268 *
1269 * @param x
1270 * The new X coordinate
1271 * @param y
1272 * The new Y coordinate
1273 */
1274 public void setPosition(int x, int y) {
1275 _x = x;
1276 _y = y;
1277
1278 updatePolygon();
1279
1280 // update the position of any dots that are constrained by this one
1281 for (Constraint c : _constraints) {
1282 Item other = c.getOppositeEnd(this);
1283
1284 // only set position if the other dot is still fixed to the
1285 // frame
1286 if (!other.isFloating()) {
1287 if (c.getType() == Constraint.HORIZONTAL
1288 && other.getY() != getY())
1289 other.setY(getY());
1290
1291 if (c.getType() == Constraint.VERTICAL
1292 && other.getX() != getX())
1293 other.setX(getX());
1294 }
1295 }
1296
1297 for (Line line : getLines())
1298 line.updatePolygon();
1299 }
1300
1301 public void setPosition(Point position) {
1302 setPosition(position.x, position.y);
1303 }
1304
1305 public void setRelativeLink() {
1306 if (_link == null)
1307 return;
1308 assert (_parent != null);
1309 // Check if the link is for the current frameset
1310 if (_parent.getFramesetName().equalsIgnoreCase(
1311 Conversion.getFrameset(_link))) {
1312 _link = "" + Conversion.getFrameNumber(_link);
1313 }
1314 }
1315
1316 /**
1317 * Sets the size of this Item. For Text this is the Font size. For Lines and
1318 * Dots this is the thickness.
1319 */
1320 public void setSize(int size) {
1321 }
1322
1323 public void setThickness(float thick) {
1324 _thickness = thick;
1325 // update the size of any lines
1326 for (Line line : getLines())
1327 line.setThickness(thick);
1328 }
1329
1330 /**
1331 * Returns the thickness (in pixels) of this Dot.
1332 *
1333 * @return The 'thickness' of this Dot. (returns -1 if the thickness is not
1334 * set).
1335 */
1336 public float getThickness() {
1337 return _thickness;
1338 }
1339
1340 /**
1341 * Sets the Color to use on the top and left sections of this Item's border.
1342 * If top is NULL, then the Item's background Color will be used.
1343 *
1344 * @param top
1345 * The Color to display in the top and left sections of this
1346 * Item's border.
1347 */
1348 public void setTopShadowColor(Color top) {
1349 _colorTopShadow = top;
1350 }
1351
1352 public void setWidth(int width) throws UnsupportedOperationException {
1353 throw new UnsupportedOperationException(
1354 "Item type does not support width attribute!");
1355 }
1356
1357 /**
1358 * Sets the position of this Item on the X axis
1359 *
1360 * @param newX
1361 * The position on the X axis to assign to this Item
1362 */
1363 public void setX(int newX) {
1364 setPosition(newX, getY());
1365 }
1366
1367 /**
1368 * Sets the position of this Item on the Y axis
1369 *
1370 * @param newY
1371 * The position on the Y axis to assign to this Item
1372 */
1373 public void setY(int newY) {
1374 setPosition(getX(), newY);
1375 }
1376
1377 /**
1378 * Paints any highlighting of this Item. This may include changing the
1379 * thickness (lines) or painting a box around the item (Text, Images). If
1380 * val is True then the Graphics Color is changed to the highlight Color, if
1381 * False then the Graphics Color is left unchanged (for clearing of
1382 * highlighting).
1383 *
1384 * @param val
1385 * True if this Item should be highlighted, false if the
1386 * highlighting is being cleared.
1387 * @return The desired mouse cursor when this Item is highlighted (negative
1388 * means no change)
1389 */
1390 public int setSelectionColor() {
1391 return setSelectionColor(DEFAULT_HIGHLIGHT);
1392 }
1393
1394 public int setSelectionColor(Color c) {
1395 _highlightThickness = DEFAULT_HIGHLIGHT_THICKNESS;
1396 if (c != null)
1397 _highlightColor = c;
1398 else
1399 _highlightColor = DEFAULT_HIGHLIGHT;
1400
1401 return Item.UNCHANGED_CURSOR;
1402 }
1403
1404 private void updateArrowPolygon() {
1405 if (getArrowheadLength() < 0 || getArrowheadRatio() < 0)
1406 _arrowhead = null;
1407 else {
1408 _arrowhead = new Polygon();
1409 _arrowhead.addPoint((int) getX(), (int) getY());
1410 _arrowhead
1411 .addPoint(
1412 (int) getX() - getArrowheadLength(),
1413 (int) (getY() - (getArrowheadLength() * getArrowheadRatio())));
1414 _arrowhead.addPoint((int) getX(), (int) getY());
1415 _arrowhead
1416 .addPoint(
1417 (int) getX() - getArrowheadLength(),
1418 (int) (getY() + (getArrowheadLength() * getArrowheadRatio())));
1419 }
1420 }
1421
1422 protected abstract void updatePolygon();
1423
1424 public void setVisible(boolean state) {
1425 this._visible = state;
1426 }
1427
1428 public boolean isVisible() {
1429 return _visible;
1430 }
1431
1432 // BROOK: Overrideable
1433 public void onRemovedFromFrame() {
1434 }
1435
1436 public void onAddedToFrame(boolean isOverlayed, int overlayLevel) {
1437 }
1438
1439 public void onParentFameHidden() {
1440 } // because of caching
1441
1442 public void onParentFameShown(boolean isOverlayed, int overlayLevel) {
1443 } // because of caching
1444
1445 public void setSelectedMode(SelectedMode mode, Color color) {
1446 setSelectionColor(color);
1447 _lastMode = _mode;
1448 _mode = mode;
1449 }
1450
1451 public void restoreLastMode(Color selectionColor) {
1452 setSelectionColor(selectionColor);
1453 if (_mode != SelectedMode.None)
1454 return;
1455 _mode = _lastMode;
1456 _lastMode = SelectedMode.None;
1457 }
1458
1459 public SelectedMode getSelectedMode() {
1460 return _mode;
1461 }
1462
1463 public void anchor() {
1464 Frame current = getCurrentFrame();
1465 setID(current.getNextItemID());
1466 setOffset(0, 0);
1467 setParent(current);
1468
1469 current.addItem(this);
1470 current.setResort(true);
1471 setRelativeLink();
1472 setFloating(false);
1473 }
1474
1475 /**
1476 * Gets the parent frame if it is set or the current frame if this item does
1477 * not have a parent set.
1478 *
1479 * @return
1480 */
1481 public Frame getCurrentFrame() {
1482 // if the item is from an overlay the parent will NOT be null
1483 if (getParent() == null) {
1484 return DisplayIO.getCurrentFrame();
1485 }
1486 return getParent();
1487 }
1488
1489 /**
1490 * Sets the list of Dots (including this one) that form a closed shape.
1491 * Passing null sets this dot back to its normal (non-enclosed) state.
1492 *
1493 * @param enclosed
1494 * The List of Dots including this one that form a closed shape,
1495 * or null.
1496 */
1497 public void setEnclosedList(List<Item> enclosed) {
1498 _enclosure = enclosed;
1499 }
1500
1501 /**
1502 * Returns the polygon that represents the shape created by all the Dots in
1503 * this Dot's enclosed list. If the list is null, then null is returned.
1504 *
1505 * @return A Polygon the same shape and position as created by the Dots in
1506 * the enclosed list.
1507 */
1508 public Polygon getEnclosedShape() {
1509 if (_enclosure == null)
1510 return null;
1511
1512 Polygon poly = new Polygon();
1513 for (Item d : _enclosure) {
1514 poly.addPoint(d.getX(), d.getY());
1515 }
1516
1517 return poly;
1518 }
1519
1520 /**
1521 * Returns the list of Dots that, along with this Dot, form an enclosed
1522 * polygon. If this Dot is not part of an enclosure null may be returned.
1523 *
1524 * @return The List of Dots that form an enclosed shape with this Dot, or
1525 * null if this Dot is not part of an enclosure.
1526 */
1527 public List<Item> getEnclosingDots() {
1528 return _enclosure;
1529 }
1530
1531 /**
1532 * Returns whether this Dot has an assigned enclosure list of other Dots.
1533 * The result is the same as getEnclosedShape() != null.
1534 *
1535 * @return True if this Dot has an enclosure list of other Dots, false
1536 * otherwise.
1537 */
1538 public boolean isEnclosed() {
1539 return _enclosure != null;
1540 }
1541
1542 public boolean isLineEnd() {
1543 return _lines.size() > 0;
1544 }
1545
1546 /**
1547 * Method that is called to notify an item that is on the end of a line that
1548 * its line has changed color.
1549 *
1550 * @param c
1551 * the new color for the line
1552 */
1553 protected void lineColorChanged(Color c) {
1554 for (Line l : getLines()) {
1555 if (l.getColor() != c)
1556 l.setColor(c);
1557 }
1558 }
1559}
Note: See TracBrowser for help on using the repository browser.