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

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

Made LOTS of changes...
Added DisplayComet
A whole bunch more stats for items and events
Changed lots of stuff for drawing better especially using text as line endpoints

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