source: trunk/src/org/expeditee/items/Dot.java@ 143

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

Fixed some repaint issues

File size: 7.7 KB
Line 
1package org.expeditee.items;
2
3import java.awt.Color;
4import java.awt.Graphics2D;
5import java.awt.Polygon;
6import java.awt.Rectangle;
7import java.util.ArrayList;
8import java.util.LinkedList;
9import java.util.List;
10
11import org.expeditee.gui.DisplayIO;
12import org.expeditee.gui.Frame;
13import org.expeditee.gui.FrameKeyboardActions;
14
15/**
16 * Represents a point on the screen. All Point objects are stored as x,y pairs
17 * with an Item ID. Note: Lines and all combinates of lines (rectangles, etc)
18 * are represented only as Points that share line IDs.
19 *
20 * @author jdm18
21 *
22 */
23public class Dot extends Item {
24
25 // Standard Item variables
26
27 private static final int _MINIMUM_DOT_SIZE = 6;
28
29 private static final int MINIMUM_DOT_SIZE = 2;
30
31 private int _pointType = Item.POINTTYPE_SQUARE;
32
33 private boolean _filled = true;
34
35 public Dot(int id) {
36 super();
37 setID(id);
38 }
39
40 /**
41 * Constructs a new Point with the given x,y coordinates and Item ID.
42 *
43 * @param x
44 * The x coordinate of this point
45 * @param y
46 * The y coordinate of this point
47 * @param id
48 * The Item ID of this Point
49 */
50 public Dot(int x, int y, int id) {
51 super();
52 setID(id);
53 setPosition(x, y);
54 }
55
56 public void setPointType(int type) {
57 _pointType = type;
58 }
59
60 public void useFilledPoints(boolean val) {
61 _filled = val;
62 }
63
64 /**
65 * Sets the 'thickness' of this Dot, that is, how many pixels this Dot
66 * should be.
67 *
68 * @param thick
69 * The number of pixels to use when displaying this Dot The Dot
70 * is displayed as a thick x thick square.
71 */
72 @Override
73 public void setThickness(float thick) {
74 super.setThickness(thick);
75
76 updatePolygon();
77 }
78
79 @Override
80 public void setColor(Color c) {
81 super.setColor(c);
82
83 // update the colour of any lines
84 for (Line line : getLines())
85 line.setColor(c);
86 }
87
88 @Override
89 public void paint(Graphics2D g) {
90 if (isHighlighted() /* && !FreeItems.getInstance().contains(this) */) {
91 Color highlightColor = getHighlightColor();
92 g.setColor(highlightColor);
93 g.setStroke(HIGHLIGHT_STROKE);
94 // g.setStroke()
95 // Draw the highlighting rectangle surrounding the dot
96 // this is drawn even if its part of a rectangle
97 Rectangle rect = getPolygon().getBounds();
98 if (_mode == HighlightMode.Enclosed ||
99 // Make sure single dots are highlighted filled
100 this.getConnected().size() <= 1)
101 g.fillRect(rect.x, rect.y, rect.width, rect.height);
102 else if (_mode == HighlightMode.Connected)
103 g.drawRect(rect.x, rect.y, rect.width, rect.height);
104 else if (_mode == HighlightMode.Normal) {
105 g.fillOval(rect.x, rect.y, rect.width, rect.height);
106 }
107 // System.out.println(_mode.toString());
108 }
109
110 // dots on lines are hidden
111 if (getLines().size() > 0)
112 return;
113
114 g.setColor(getPaintColor());
115
116 int thick = (int) getThickness();
117 if (thick < MINIMUM_DOT_SIZE)
118 thick = MINIMUM_DOT_SIZE;
119
120 int width = thick / 2;
121
122 if (_pointType == Item.POINTTYPE_CIRCLE) {
123 int points = 40;
124
125 double radians = 0.0;
126 int xPoints[] = new int[points];
127 int yPoints[] = new int[xPoints.length];
128
129 for (int i = 0; i < xPoints.length; i++) {
130 xPoints[i] = getX() + (int) (width * Math.cos(radians));
131 yPoints[i] = getY() + (int) (width * Math.sin(radians));
132 radians += (2.0 * Math.PI) / xPoints.length;
133 }
134
135 if (_filled)
136 g.fillPolygon(new Polygon(xPoints, yPoints, xPoints.length));
137 else
138 g.drawPolygon(new Polygon(xPoints, yPoints, xPoints.length));
139 } else {
140 if (_filled)
141 g.fillRect(getX() - width, getY() - width, thick, thick);
142 else
143 g.drawRect(getX() - width, getY() - width, thick, thick);
144 }
145
146 }
147
148 /**
149 * Updates the points of the polygon surrounding this Dot
150 */
151 public void updatePolygon() {
152 int thick = Math.round(getThickness());
153 // Sets a minimum size for the dot
154 thick = Math.max(thick, _MINIMUM_DOT_SIZE);
155
156 int x = getX() - thick / 2;
157 int y = getY() - thick / 2;
158
159 _poly = new Polygon();
160 _poly.addPoint(x - getGravity(), y - getGravity());
161 _poly.addPoint(x + thick + getGravity(), y - getGravity());
162 _poly.addPoint(x + thick + getGravity(), y + thick + getGravity());
163 _poly.addPoint(x - getGravity(), y + thick + getGravity());
164 }
165
166 @Override
167 public Item copy() {
168 Dot copy = new Dot(getX(), getY(), getID());
169
170 Item.DuplicateItem(this, copy);
171
172 copy.setThickness(getThickness());
173 copy.setPointType(_pointType);
174 copy.useFilledPoints(_filled);
175
176 return copy;
177 }
178
179 @Override
180 public int setHighlightColor() {
181 super.setHighlightColor();
182
183 return Item.DEFAULT_CURSOR;
184 }
185
186 @Override
187 public void setAnnotation(boolean val) {
188 DisplayIO.setCursorPosition(this.getPosition());
189 FrameKeyboardActions.replaceDot(this, '@');
190 }
191
192 @Override
193 public Item merge(Item merger, int mouseX, int mouseY) {
194 // if the item being merged with is another Dot
195 if (merger instanceof Dot) {
196 if (merger.hasEnclosures() || hasEnclosures())
197 return merger;
198
199 Item dot = (Item) merger;
200 merger.setPosition(this.getPosition());
201 // prevent concurrency issues if removing lines
202 List<Line> lines = new ArrayList<Line>();
203 lines.addAll(dot.getLines());
204
205 for (Line line : lines) {
206 // remove lines that are in common
207 if (getLines().contains(line)) {
208 dot.removeLine(line);
209 removeLine(line);
210 } else {
211 // check for duplicated lines as a result of merging
212 Item check = (Item) line.getOppositeEnd(dot);
213 boolean dup = false;
214
215 for (Line l : getLines()) {
216 Item opposite = l.getOppositeEnd(this);
217
218 if (check == opposite) {
219 line.getStartItem().removeLine(line);
220 line.getEndItem().removeLine(line);
221 dup = true;
222 break;
223 }
224 }
225
226 if (!dup)
227 line.replaceLineEnd(dot, this);
228 }
229 }
230
231 setThickness(dot.getThickness());
232 setColor(dot.getColor());
233 setFillColor(dot.getFillColor());
234
235 return null;
236 }
237
238 if (merger instanceof Text) {
239 merger.setPosition(this.getPosition());
240 List<Line> lines = new LinkedList<Line>();
241 lines.addAll(getLines());
242 for (Line line : lines)
243 line.replaceLineEnd(this, merger);
244 this.delete();
245 return merger;
246 }
247
248 // if the item being merged with is a Line
249 if (merger instanceof Line) {
250 Line line = (Line) merger;
251 // if this dot is part of the line then keep it, otherwise it
252 // can be removed
253 if (line.getOppositeEnd(this) != null && getLines().contains(line))
254 return merger;
255 else
256 return null;
257 }
258
259 return merger;
260 }
261
262 @Override
263 public String getTypeAndID() {
264 return "P " + getID();
265 }
266
267 @Override
268 public void delete() {
269 super.delete();
270
271 for (Line l : this.getLines())
272 l.delete();
273 }
274
275 @Override
276 public void anchor() {
277 Frame current = getParentOrCurrentFrame();
278 // This is to make lines anchored across frames be on one frame
279 for (Line l : getLines()) {
280 Frame parent = l.getOppositeEnd(this).getParent();
281 if (parent != null && parent != current) {
282 this.setParent(parent);
283 if (DisplayIO.getCurrentSide() == 0)
284 this.setX(this.getX() - DisplayIO.getMiddle());
285 else
286 this.setX(this.getX() + DisplayIO.getMiddle());
287 }
288 break;
289 }
290
291 super.anchor();
292
293 // TODO is the code below needed... what for?
294 for (Line line : getLines()) {
295 if (line.getID() < 0 && !current.getItems().contains(line)) {
296 line.setID(current.getNextItemID());
297 line.setHighlightColor();
298 // Mike: Why was this line here?
299 // anchor(line);
300 }
301 }
302 }
303
304 @Override
305 public void addLine(Line line) {
306 super.addLine(line);
307 line.setColor(getColor());
308 line.setThickness(getThickness());
309 line.setLinePattern(getLinePattern());
310 }
311
312 @Override
313 public void lineColorChanged(Color c) {
314 if (getColor() != c) {
315 setColor(c);
316 }
317 }
318
319 @Override
320 public boolean dontSave() {
321 if (getThickness() <= 1 && (getLines().size() == 0)
322 && getConstraints().size() == 0) {
323 return true;
324 }
325 return super.dontSave();
326 }
327}
Note: See TracBrowser for help on using the repository browser.