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

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

Added lots of stuff

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