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

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

Fixed some bugs...
AbstractCharts can not be copied, resized, etc

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