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

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

New expeditee version

File size: 8.3 KB
Line 
1package org.expeditee.items;
2
3import java.awt.Graphics2D;
4import java.awt.Polygon;
5import java.util.ArrayList;
6import java.util.LinkedList;
7import java.util.List;
8
9/**
10 * Represents a point on the screen. All Point objects are stored as x,y pairs
11 * with an Item ID. Note: Lines and all combinates of lines (rectangles, etc)
12 * are represented only as Points that share line IDs.
13 *
14 * @author jdm18
15 *
16 */
17public class Dot extends Item {
18
19 // Standard Item variables
20
21 // contains all dots (including this one) that form an enclosure
22 // if this dot is part of an enclosing shape
23 private List<Dot> _enclosure = null;
24
25 // the polygon surrounding this point, used for 'gravity'
26 private Polygon _poly = null;
27
28 // The thickness (in pixels) of this Point
29 private float _thickness = -1;
30
31 private int _pointType = Item.POINTTYPE_SQUARE;
32
33 private boolean _filled = true;
34
35 protected boolean _filledHighlight = false;
36
37 public Dot(int id) {
38 super();
39 setID(id);
40 }
41
42 /**
43 * Constructs a new Point with the given x,y coordinates and Item ID.
44 *
45 * @param x
46 * The x coordinate of this point
47 * @param y
48 * The y coordinate of this point
49 * @param id
50 * The Item ID of this Point
51 */
52 public Dot(int x, int y, int id) {
53 super();
54 setID(id);
55 setPosition(x, y);
56 }
57
58 public void setPointType(int type) {
59 _pointType = type;
60 }
61
62 public void useFilledPoints(boolean val) {
63 _filled = val;
64 }
65
66 @Override
67 protected boolean hasVisibleArrow() {
68 return getArrowheadRatio() != 0 && getArrowheadLength() != 0;
69 }
70
71 /**
72 * Sets the 'thickness' of this Dot, that is, how many pixels this Dot
73 * should be.
74 *
75 * @param thick
76 * The number of pixels to use when displaying this Dot The Dot
77 * is displayed as a thick x thick square.
78 */
79 @Override
80 public void setThickness(float thick) {
81 _thickness = thick;
82
83 updatePolygon();
84
85 // update the size of any lines
86 for (Line line : getLines())
87 line.setThickness(thick);
88 }
89
90 /**
91 * Returns the thickness (in pixels) of this Dot.
92 *
93 * @return The 'thickness' of this Dot. (returns -1 if the thickness is not
94 * set).
95 */
96 @Override
97 public float getThickness() {
98 return _thickness;
99 }
100
101 public void paintFill(Graphics2D g) {
102 if (getFillColor() != null && getEnclosingDots() != null) {
103 g.setColor(getFillColor());
104 g.fillPolygon(getEnclosedShape());
105 }
106 }
107
108 @Override
109 public void paint(Graphics2D g) {
110 if (isHighlighted()) {
111 g.setColor(getHighlightColor());
112 // Draw the highlighting rectangle surrounding the dot
113 // this is drawn even if its part of a rectangle
114 if (_filledHighlight)
115 g.fillPolygon(getPolygon());
116 else
117 g.drawPolygon(getPolygon());
118 }
119
120 // dots on lines are hidden
121 if (getLines().size() > 0)
122 return;
123
124 g.setColor(getPaintColor());
125
126 int thick = (int) _thickness;
127 if (thick < 2)
128 thick = 2;
129
130 int width = thick / 2;
131
132 // if(_thickness < 1)
133 /*
134 * if(_filled) g.fillRect(getX(), getY(), thick,thick); else
135 * g.drawRect(getX(), getY(), thick,thick); else
136 */
137
138 if (_pointType == Item.POINTTYPE_CIRCLE) {
139 int points = 40;
140
141 double radians = 0.0;
142 int xPoints[] = new int[points];
143 int yPoints[] = new int[xPoints.length];
144
145 for (int i = 0; i < xPoints.length; i++) {
146 xPoints[i] = getX() + (int) (width * Math.cos(radians));
147 yPoints[i] = getY() + (int) (width * Math.sin(radians));
148 radians += (2.0 * Math.PI) / xPoints.length;
149 }
150
151 if (_filled)
152 g.fillPolygon(new Polygon(xPoints, yPoints, xPoints.length));
153 else
154 g.drawPolygon(new Polygon(xPoints, yPoints, xPoints.length));
155 } else {
156 if (_filled)
157 g.fillRect(getX() - width, getY() - width, thick, thick);
158 else
159 g.drawRect(getX() - width, getY() - width, thick, thick);
160 }
161
162 }
163
164 /**
165 * Updates the points of the polygon surrounding this Dot
166 */
167 protected void updatePolygon() {
168 int thick = (int) Math.ceil(getThickness());
169 // Sets a minimum size for the dot
170 thick = Math.max(thick, 10);
171
172 int x = getX() - thick / 2;
173 int y = getY() - thick / 2;
174
175 _poly = new Polygon();
176 _poly.addPoint(x - getGravity(), y - getGravity());
177 _poly.addPoint(x + thick + getGravity(), y - getGravity());
178 _poly.addPoint(x + thick + getGravity(), y + thick + getGravity());
179 _poly.addPoint(x - getGravity(), y + thick + getGravity());
180 }
181
182 @Override
183 public Polygon getPolygon() {
184 if (_poly == null)
185 updatePolygon();
186
187 Polygon external = new Polygon(_poly.xpoints, _poly.ypoints,
188 _poly.npoints);
189
190 return external;
191 }
192
193 @Override
194 public Dot copy() {
195 Dot copy = new Dot(getX(), getY(), getID());
196
197 Item.DuplicateItem(this, copy);
198
199 copy.setThickness(getThickness());
200 copy.setPointType(_pointType);
201 copy.useFilledPoints(_filled);
202
203 return copy;
204 }
205
206 @Override
207 public int showHighlight(boolean val) {
208 super.showHighlight(val);
209
210 return Item.DEFAULT_CURSOR;
211 }
212
213 @Override
214 public int getSize() {
215 return (int) getThickness();
216 }
217
218 @Override
219 public void setSize(int size) {
220 }
221
222 @Override
223 public void setAnnotation(boolean val) {
224 }
225
226 @Override
227 public boolean isAnnotation() {
228 return false;
229 }
230
231 @Override
232 public Item merge(Item merger, int mouseX, int mouseY) {
233 // if the item being merged with is another Dot
234 if (merger instanceof Dot) {
235 Dot dot = (Dot) merger;
236
237 // prevent concurrency issues if removing lines
238 List<Line> lines = new ArrayList<Line>();
239 lines.addAll(dot.getLines());
240
241 for (Line line : lines) {
242 // remove lines that are in common
243 if (getLines().contains(line)) {
244 dot.removeLine(line);
245 removeLine(line);
246 } else {
247 // check for duplicated lines as a result of merging
248 Dot check = (Dot) line.getOppositeEnd(dot);
249 boolean dup = false;
250
251 for (Line l : getLines()) {
252 Item opposite = l.getOppositeEnd(this);
253
254 if (check == opposite) {
255 line.getStartItem().removeLine(line);
256 line.getEndItem().removeLine(line);
257 dup = true;
258 break;
259 }
260 }
261
262 if (!dup)
263 line.replaceEnd(dot, this);
264 }
265 }
266
267 setThickness(dot.getThickness());
268 setColor(dot.getColor());
269 setFillColor(dot.getFillColor());
270
271 return null;
272 }
273
274 if (merger instanceof Text) {
275 List<Line> lines = new LinkedList<Line>();
276 lines.addAll(getLines());
277 for (Line line : lines)
278 line.replaceEnd(this, merger);
279
280 removeAllLines();
281 return merger;
282 }
283
284 // if the item being merged with is a Line
285 if (merger instanceof Line) {
286 Line line = (Line) merger;
287 // if this dot is part of the line then keep it, otherwise it
288 // can be removed
289 if (line.getOppositeEnd(this) != null && getLines().contains(line))
290 return merger;
291 else
292 return null;
293 }
294
295 return merger;
296 }
297
298 /**
299 * Sets the list of Dots (including this one) that form a closed shape.
300 * Passing null sets this dot back to its normal (non-enclosed) state.
301 *
302 * @param enclosed
303 * The List of Dots including this one that form a closed shape,
304 * or null.
305 */
306 public void setEnclosedList(List<Dot> enclosed) {
307 _enclosure = enclosed;
308 }
309
310 /**
311 * Returns the polygon that represents the shape created by all the Dots in
312 * this Dot's enclosed list. If the list is null, then null is returned.
313 *
314 * @return A Polygon the same shape and position as created by the Dots in
315 * the enclosed list.
316 */
317 public Polygon getEnclosedShape() {
318 if (_enclosure == null)
319 return null;
320
321 Polygon poly = new Polygon();
322 for (Dot d : _enclosure) {
323 poly.addPoint(d.getX(), d.getY());
324 }
325
326 return poly;
327 }
328
329 /**
330 * Returns the list of Dots that, along with this Dot, form an enclosed
331 * polygon. If this Dot is not part of an enclosure null may be returned.
332 *
333 * @return The List of Dots that form an enclosed shape with this Dot, or
334 * null if this Dot is not part of an enclosure.
335 */
336 public List<Dot> getEnclosingDots() {
337 return _enclosure;
338 }
339
340 /**
341 * Returns whether this Dot has an assigned enclosure list of other Dots.
342 * The result is the same as getEnclosedShape() != null.
343 *
344 * @return True if this Dot has an enclosure list of other Dots, false
345 * otherwise.
346 */
347 public boolean isEnclosed() {
348 return _enclosure != null;
349 }
350
351 @Override
352 public String getTypeAndID() {
353 return "P " + getID();
354 }
355
356 @Override
357 public void setFilledHighlight(boolean value) {
358 _filledHighlight = value;
359 }
360
361 @Override
362 public void delete() {
363 super.delete();
364
365 for(Line l: this.getLines())
366 l.delete();
367 }
368}
Note: See TracBrowser for help on using the repository browser.