source: trunk/org/expeditee/items/Dot.java@ 4

Last change on this file since 4 was 4, checked in by davidb, 16 years ago

Starting source code to Expeditee

File size: 7.9 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 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 @Override
65 protected boolean hasVisibleArrow() {
66 return getArrowheadRatio() != 0 && getArrowheadLength() != 0;
67 }
68
69 /**
70 * Sets the 'thickness' of this Dot, that is, how many pixels this Dot
71 * should be.
72 *
73 * @param thick
74 * The number of pixels to use when displaying this Dot The Dot
75 * is displayed as a thick x thick square.
76 */
77 @Override
78 public void setThickness(float thick) {
79 _thickness = thick;
80
81 updatePolygon();
82
83 // update the size of any lines
84 for (Line line : getLines())
85 line.setThickness(thick);
86 }
87
88 /**
89 * Returns the thickness (in pixels) of this Dot.
90 *
91 * @return The 'thickness' of this Dot. (returns -1 if the thickness is not
92 * set).
93 */
94 @Override
95 public float getThickness() {
96 return _thickness;
97 }
98
99 public void paintFill(Graphics2D g) {
100 if (getFillColor() != null && getEnclosingDots() != null) {
101 g.setColor(getFillColor());
102 g.fillPolygon(getEnclosedShape());
103 }
104 }
105
106 @Override
107 public void paint(Graphics2D g) {
108 if (isHighlighted()) {
109 g.setColor(getHighlightColor());
110 g.drawPolygon(getPolygon());
111 }
112
113 // dots on lines are hidden
114 if (getLines().size() > 0)
115 return;
116
117 g.setColor(getPaintColor());
118
119 int thick = (int) _thickness;
120 if (thick < 2)
121 thick = 2;
122
123 int width = thick / 2;
124
125 // if(_thickness < 1)
126 /*
127 * if(_filled) g.fillRect(getX(), getY(), thick,thick); else
128 * g.drawRect(getX(), getY(), thick,thick); else
129 */
130
131 if (_pointType == Item.POINTTYPE_CIRCLE) {
132 int points = 40;
133
134 double radians = 0.0;
135 int xPoints[] = new int[points];
136 int yPoints[] = new int[xPoints.length];
137
138 for (int i = 0; i < xPoints.length; i++) {
139 xPoints[i] = getX() + (int) (width * Math.cos(radians));
140 yPoints[i] = getY() + (int) (width * Math.sin(radians));
141 radians += (2.0 * Math.PI) / xPoints.length;
142 }
143
144 if (_filled)
145 g.fillPolygon(new Polygon(xPoints, yPoints, xPoints.length));
146 else
147 g.drawPolygon(new Polygon(xPoints, yPoints, xPoints.length));
148 } else {
149 if (_filled)
150 g.fillRect(getX() - width, getY() - width, thick, thick);
151 else
152 g.drawRect(getX() - width, getY() - width, thick, thick);
153 }
154
155 }
156
157 /**
158 * Updates the points of the polygon surrounding this Dot
159 */
160 protected void updatePolygon() {
161 int thick = (int) Math.ceil(getThickness());
162 // Sets a minimum size for the dot
163 thick = Math.max(thick, 10);
164
165 int x = getX() - thick / 2;
166 int y = getY() - thick / 2;
167
168 _poly = new Polygon();
169 _poly.addPoint(x - getGravity(), y - getGravity());
170 _poly.addPoint(x + thick + getGravity(), y - getGravity());
171 _poly.addPoint(x + thick + getGravity(), y + thick + getGravity());
172 _poly.addPoint(x - getGravity(), y + thick + getGravity());
173 }
174
175 @Override
176 public Polygon getPolygon() {
177 if (_poly == null)
178 updatePolygon();
179
180 Polygon external = new Polygon(_poly.xpoints, _poly.ypoints,
181 _poly.npoints);
182
183 return external;
184 }
185
186 @Override
187 public Dot copy() {
188 Dot copy = new Dot(getX(), getY(), getID());
189
190 Item.DuplicateItem(this, copy);
191
192 copy.setThickness(getThickness());
193 copy.setPointType(_pointType);
194 copy.useFilledPoints(_filled);
195
196 return copy;
197 }
198
199 @Override
200 public int showHighlight(boolean val) {
201 super.showHighlight(val);
202
203 return Item.DEFAULT_CURSOR;
204 }
205
206 @Override
207 public int getSize() {
208 return (int) getThickness();
209 }
210
211 @Override
212 public void setSize(int size) {
213 }
214
215 @Override
216 public void setAnnotation(boolean val) {
217 }
218
219 @Override
220 public boolean isAnnotation() {
221 return false;
222 }
223
224 @Override
225 public Item merge(Item merger, int mouseX, int mouseY) {
226 // if the item being merged with is another Dot
227 if (merger instanceof Dot) {
228 Dot dot = (Dot) merger;
229
230 // prevent concurrency issues if removing lines
231 List<Line> lines = new ArrayList<Line>();
232 lines.addAll(dot.getLines());
233
234 for (Line line : lines) {
235 // remove lines that are in common
236 if (getLines().contains(line)) {
237 dot.removeLine(line);
238 removeLine(line);
239 } else {
240 // check for duplicated lines as a result of merging
241 Dot check = (Dot) line.getOppositeEnd(dot);
242 boolean dup = false;
243
244 for (Line l : getLines()) {
245 Item opposite = l.getOppositeEnd(this);
246
247 if (check == opposite) {
248 line.getStartItem().removeLine(line);
249 line.getEndItem().removeLine(line);
250 dup = true;
251 break;
252 }
253 }
254
255 if (!dup)
256 line.replaceEnd(dot, this);
257 }
258 }
259
260 setThickness(dot.getThickness());
261 setColor(dot.getColor());
262 setFillColor(dot.getFillColor());
263
264 return null;
265 }
266
267 if (merger instanceof Text) {
268 List<Line> lines = new LinkedList<Line>();
269 lines.addAll(getLines());
270 for (Line line : lines)
271 line.replaceEnd(this, merger);
272
273 removeAllLines();
274 return merger;
275 }
276
277 // if the item being merged with is a Line
278 if (merger instanceof Line) {
279 Line line = (Line) merger;
280 // if this dot is part of the line then keep it, otherwise it
281 // can be removed
282 if (line.getOppositeEnd(this) != null && getLines().contains(line))
283 return merger;
284 else
285 return null;
286 }
287
288 return merger;
289 }
290
291 /**
292 * Sets the list of Dots (including this one) that form a closed shape.
293 * Passing null sets this dot back to its normal (non-enclosed) state.
294 *
295 * @param enclosed
296 * The List of Dots including this one that form a closed shape,
297 * or null.
298 */
299 public void setEnclosedList(List<Dot> enclosed) {
300 _enclosure = enclosed;
301 }
302
303 /**
304 * Returns the polygon that represents the shape created by all the Dots in
305 * this Dot's enclosed list. If the list is null, then null is returned.
306 *
307 * @return A Polygon the same shape and position as created by the Dots in
308 * the enclosed list.
309 */
310 public Polygon getEnclosedShape() {
311 if (_enclosure == null)
312 return null;
313
314 Polygon poly = new Polygon();
315 for (Dot d : _enclosure) {
316 poly.addPoint(d.getX(), d.getY());
317 }
318
319 return poly;
320 }
321
322 /**
323 * Returns the list of Dots that, along with this Dot, form an enclosed
324 * polygon. If this Dot is not part of an enclosure null may be returned.
325 *
326 * @return The List of Dots that form an enclosed shape with this Dot, or
327 * null if this Dot is not part of an enclosure.
328 */
329 public List<Dot> getEnclosingDots() {
330 return _enclosure;
331 }
332
333 /**
334 * Returns whether this Dot has an assigned enclosure list of other Dots.
335 * The result is the same as getEnclosedShape() != null.
336 *
337 * @return True if this Dot has an enclosure list of other Dots, false
338 * otherwise.
339 */
340 public boolean isEnclosed() {
341 return _enclosure != null;
342 }
343
344 @Override
345 public String getTypeAndID() {
346 return "P " + getID();
347 }
348}
Note: See TracBrowser for help on using the repository browser.