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

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

Items that are completely off the screen to the left or above are no longer saved in the file

File size: 37.1 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 /**
1433 * Raised whenever the item is removed, added, no longer in view (That is, when it is
1434 * not on any of the current frames, of overlays of the current frames) or
1435 * has become visible. That is, when it is either on a current frames, or an overlay of a current frame.
1436 * @param e The event
1437 */
1438 public void onParentStateChanged(ItemParentStateChangedEvent e) {}
1439
1440 public void setSelectedMode(SelectedMode mode, Color color) {
1441 setSelectionColor(color);
1442 _lastMode = _mode;
1443 _mode = mode;
1444 }
1445
1446 public void restoreLastMode(Color selectionColor) {
1447 setSelectionColor(selectionColor);
1448 if (_mode != SelectedMode.None)
1449 return;
1450 _mode = _lastMode;
1451 _lastMode = SelectedMode.None;
1452 }
1453
1454 public SelectedMode getSelectedMode() {
1455 return _mode;
1456 }
1457
1458 public void anchor() {
1459 Frame current = getCurrentFrame();
1460 setID(current.getNextItemID());
1461 setOffset(0, 0);
1462 setParent(current);
1463
1464 current.addItem(this);
1465 current.setResort(true);
1466 setRelativeLink();
1467 setFloating(false);
1468 }
1469
1470 /**
1471 * Gets the parent frame if it is set or the current frame if this item does
1472 * not have a parent set.
1473 *
1474 * @return
1475 */
1476 public Frame getCurrentFrame() {
1477 // if the item is from an overlay the parent will NOT be null
1478 if (getParent() == null) {
1479 return DisplayIO.getCurrentFrame();
1480 }
1481 return getParent();
1482 }
1483
1484 /**
1485 * Sets the list of Dots (including this one) that form a closed shape.
1486 * Passing null sets this dot back to its normal (non-enclosed) state.
1487 *
1488 * @param enclosed
1489 * The List of Dots including this one that form a closed shape,
1490 * or null.
1491 */
1492 public void setEnclosedList(List<Item> enclosed) {
1493 _enclosure = enclosed;
1494 }
1495
1496 /**
1497 * Returns the polygon that represents the shape created by all the Dots in
1498 * this Dot's enclosed list. If the list is null, then null is returned.
1499 *
1500 * @return A Polygon the same shape and position as created by the Dots in
1501 * the enclosed list.
1502 */
1503 public Polygon getEnclosedShape() {
1504 if (_enclosure == null)
1505 return null;
1506
1507 Polygon poly = new Polygon();
1508 for (Item d : _enclosure) {
1509 poly.addPoint(d.getX(), d.getY());
1510 }
1511
1512 return poly;
1513 }
1514
1515 /**
1516 * Returns the list of Dots that, along with this Dot, form an enclosed
1517 * polygon. If this Dot is not part of an enclosure null may be returned.
1518 *
1519 * @return The List of Dots that form an enclosed shape with this Dot, or
1520 * null if this Dot is not part of an enclosure.
1521 */
1522 public List<Item> getEnclosingDots() {
1523 return _enclosure;
1524 }
1525
1526 /**
1527 * Returns whether this Dot has an assigned enclosure list of other Dots.
1528 * The result is the same as getEnclosedShape() != null.
1529 *
1530 * @return True if this Dot has an enclosure list of other Dots, false
1531 * otherwise.
1532 */
1533 public boolean isEnclosed() {
1534 return _enclosure != null;
1535 }
1536
1537 public boolean isLineEnd() {
1538 return _lines.size() > 0;
1539 }
1540
1541 /**
1542 * Method that is called to notify an item that is on the end of a line that
1543 * its line has changed color.
1544 *
1545 * @param c
1546 * the new color for the line
1547 */
1548 protected void lineColorChanged(Color c) {
1549 for (Line l : getLines()) {
1550 if (l.getColor() != c)
1551 l.setColor(c);
1552 }
1553 }
1554
1555 /**
1556 * Checks if this item is off the left or top of the screen
1557 * @return
1558 */
1559 public boolean offScreen() {
1560 Rectangle itemRect = getArea().getBounds();
1561 //Check that the bottom right corner of this item is on the screen
1562 if (itemRect.x + itemRect.width >= 0 && itemRect.y + itemRect.height >= 0)
1563 return false;
1564 //Check if all the items it is connected to are offscreen
1565 for(Item i: getAllConnected()){
1566 Rectangle iRect = i.getArea().getBounds();
1567 //Check that the bottom right corner of this item is on the screen
1568 if (iRect.x + iRect.width >= 0 && iRect.y + iRect.height >= 0) {
1569 return false;
1570 }
1571 }
1572 return true;
1573 }
1574}
Note: See TracBrowser for help on using the repository browser.