Source Code Cross Referenced for DraggablePoint.java in  » Science » jcm1-source » edu » hws » jcm » draw » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Science » jcm1 source » edu.hws.jcm.draw 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*************************************************************************
002:         *                                                                        *
003:         *   1) This source code file, in unmodified form, and compiled classes   *
004:         *      derived from it can be used and distributed without restriction,  *
005:         *      including for commercial use.  (Attribution is not required       *
006:         *      but is appreciated.)                                              *
007:         *                                                                        *
008:         *    2) Modified versions of this file can be made and distributed       *
009:         *       provided:  the modified versions are put into a Java package     *
010:         *       different from the original package, edu.hws;  modified          *
011:         *       versions are distributed under the same terms as the original;   *
012:         *       and the modifications are documented in comments.  (Modification *
013:         *       here does not include simply making subclasses that belong to    *
014:         *       a package other than edu.hws, which can be done without any      *
015:         *       restriction.)                                                    *
016:         *                                                                        *
017:         *   David J. Eck                                                         *
018:         *   Department of Mathematics and Computer Science                       *
019:         *   Hobart and William Smith Colleges                                    *
020:         *   Geneva, New York 14456,   USA                                        *
021:         *   Email: eck@hws.edu          WWW: http://math.hws.edu/eck/            *
022:         *                                                                        *
023:         *************************************************************************/package edu.hws.jcm.draw;
024:
025:        import java.awt.*;
026:        import java.awt.event.*;
027:        import edu.hws.jcm.data.*;
028:        import edu.hws.jcm.awt.*;
029:
030:        /**
031:         * A DraggablePoint can be added to a DisplayCanvas, where it appears as a small disk, square, or
032:         * cross.  (The visual style is a settable property.)  This object can be dragged with the mouse,
033:         * within the limits of the CoordinateRect that contains the DraggablePoint.  Either the x- or
034:         * y-value of the point can be clamped to a specified Value.  Typically, the y-value might
035:         * be given by some function of the x-value.  In that case, the point is constrained to move
036:         * along the graph of the function.  Or the x- or y-value can be clamped to a constant to make
037:         * the point move along a vertical or horizontal line.  Two Variables are associated with
038:         * the DraggablePoint.  These Variables represent the x- and y- values of the point.  Each Variable
039:         * implements the Tieable interface, so it can be synchronized with other Tieable values such as
040:         * a VariableIput or VariableSlider.
041:         */
042:
043:        public class DraggablePoint extends Drawable implements  InputObject,
044:                Draggable {
045:
046:            /**
047:             * A style constant that specifies the visual appearance of a DraggablePoint to be a disk.
048:             */
049:            public static final int DISK = 0;
050:
051:            /**
052:             * A style constant that specifies the visual appearance of a DraggablePoint to be a square.
053:             */
054:            public static final int SQUARE = 1;
055:
056:            /**
057:             * A style constant that specifies the visual appearance of a DraggablePoint to be a cross.
058:             */
059:            public static final int CROSS = 2;
060:
061:            private int radius; // Radius of the point.
062:            private Color color; // Color of the point.
063:            private Color ghostColor; // Color used for point when it is undefined or outside the CoordinateRect.
064:            private int style; // One of the above style constants, DISK by default.
065:            private double xLoc, yLoc; // The current x- and y-values of the point.
066:            private int xPosition, yPosition; // The pixel position of the point.
067:            private boolean useGhost; // This is true if the point is a "ghost" (undefined or outside the CoordinateRect).
068:            private DPV xVar, yVar; // The Variables that represent the x- and y-values; DPV is a private nested class, defined below.
069:            private Controller onUserAction; // A Controller whose compute method is called when the user drags the point.
070:            private Value clampX, clampY; // Values used to clamp the x- and y-values.  Only one can be non-null.
071:
072:            /**
073:             * Create a DraggablePoint with default values for style, radius, color.  The point appears as a dark gray disk of radius 4.
074:             */
075:            public DraggablePoint() {
076:                this (DISK);
077:            }
078:
079:            /**
080:             * Create a DraggablePoint with specified visual style.  Radius is 4, color is darkGray, and
081:             * ghostColor is lightGray.
082:             *
083:             * @param style One of the style constants DraggablePoint.DISK, DraggablePoint.SQUARE, or DraggablePoint.CROSS.
084:             */
085:            public DraggablePoint(int style) {
086:                if (style >= 0 && style <= 2)
087:                    this .style = style;
088:                setColor(Color.darkGray);
089:                setGhostColor(Color.lightGray);
090:                radius = 4;
091:                xPosition = -10000;
092:                xLoc = Double.NaN;
093:                yLoc = Double.NaN;
094:                xVar = new DPV(true);
095:                yVar = new DPV(false);
096:            }
097:
098:            /**
099:             * Clamp the x-value of the point to v.  That is, if v is not null, then whenever the location of the point
100:             * changes, its x-value is modified to v.getVal().  Note that if v is non-null then any clamp Value
101:             * specified for y will be cleared since x and y cannot both be clamped.
102:             */
103:            public void clampX(Value v) {
104:                clampX = v;
105:                if (v != null)
106:                    clampY = null;
107:                checkClamp();
108:                needsRedraw();
109:            }
110:
111:            /**
112:             * Clamp the y-value of the point to v.  That is, if v is not null, then whenever the location of the point
113:             * changes, its y-value is modified to v.getVal().  Note that if v is non-null then any clamp Value
114:             * specified for x will be cleared since x and y cannot both be clamped.
115:             */
116:            public void clampY(Value v) {
117:                clampY = v;
118:                if (v != null)
119:                    clampX = null;
120:                checkClamp();
121:                needsRedraw();
122:            }
123:
124:            /**
125:             * Clamp the x-value of the point to the constant x, so that the point is constrained to a vertical line.
126:             */
127:            public void clampX(double x) {
128:                clampX(new Constant(x));
129:            }
130:
131:            /**
132:             * Clamp the y-value of the point to the constant y, so that the point is constrained to a horizontal line.
133:             */
134:            public void clampY(double y) {
135:                clampY(new Constant(y));
136:            }
137:
138:            /**
139:             * Clamp the x-value of the point to the function f, so that the point is constrained to move along the graph of x = f(y).
140:             * f must be a function of one variable.
141:             */
142:            public void clampX(Function f) {
143:                if (f != null)
144:                    clampX(new ValueMath(f, xVar));
145:            }
146:
147:            /**
148:             * Clamp the y-value of the point to the function f, so that the point is constrained to move along the graph of y = f(x).
149:             * f must be a function of one variable.
150:             */
151:            public void clampY(Function f) {
152:                if (f != null)
153:                    clampY(new ValueMath(f, xVar));
154:            }
155:
156:            /**
157:             * Get the radius used for drawing the point.  The point's height and width are given by two times the radius.
158:             */
159:            public int getRadius() {
160:                return radius;
161:            }
162:
163:            /**
164:             * Set the radius that determines the size of the point when it is drawn.
165:             * The point's height and width are given by two times the radius.
166:             */
167:            public void setRadius(int r) {
168:                if (r > 0) {
169:                    radius = r;
170:                    needsRedraw();
171:                }
172:            }
173:
174:            /**
175:             *  Set the visual style of the point.  The style should be one of the constants
176:             *  DraggablePoint.DISK, DraggablePoint.SQUARE, or DraggablePoint.CROSS.  If it is not,
177:             *  then nothing is done.
178:             */
179:            public void setStyle(int style) {
180:                if (style >= 0 && style <= 2) {
181:                    this .style = style;
182:                    needsRedraw();
183:                }
184:            }
185:
186:            /**
187:             *  Get the visual style of the point, which must be one of the constants
188:             *  DraggablePoint.DISK, DraggablePoint.SQUARE, or DraggablePoint.CROSS.
189:             */
190:            public int getStyle() {
191:                return style;
192:            }
193:
194:            /**
195:             * Get the variable that represents the current x-value of the point. (Note that this
196:             * variable can be type-cast to type Tieable.)
197:             */
198:            public Variable getXVar() {
199:                return xVar;
200:            }
201:
202:            /**
203:             * Get the variable that represents the current y-value of the point. (Note that this
204:             * variable can be type-cast to type Tieable.)
205:             */
206:            public Variable getYVar() {
207:                return yVar;
208:            }
209:
210:            /**
211:             * Get the color used for drawing the point.
212:             */
213:            public Color getColor() {
214:                return color;
215:            }
216:
217:            /**
218:             * Set the color to be used for drawing the point.  If the specified Color value is
219:             * null, then nothing is done.
220:             */
221:            public void setColor(Color c) {
222:                if (c != null) {
223:                    color = c;
224:                    needsRedraw();
225:                }
226:            }
227:
228:            /**
229:             * Get the "ghostColor" of the point. This color is used for drawing the point when its x-value
230:             * or y-value is undefined or outside the range of values on the CoordinateRect that contains
231:             * the point.  (This can happen because of clamping of values.  It can also happen if the limits
232:             * on the CoordinateRect are changed.)
233:             */
234:            public Color getGhostColor() {
235:                return ghostColor;
236:            }
237:
238:            /**
239:             * Set the ghoseColor to be used for drawing the point when it location is undefined or is outside the
240:             * proper limits.  If the specified Color value is null, then nothing is done.
241:             */
242:            public void setGhostColor(Color c) {
243:                if (c != null) {
244:                    ghostColor = c;
245:                    needsRedraw();
246:                }
247:            }
248:
249:            /**
250:             * Set the Controller that is to be notified when the user drags the point.  (The compute() method
251:             * of the Controller is called.)  If the Controller value is null, then no notification is done.
252:             */
253:            public void setOnUserAction(Controller c) {
254:                onUserAction = c;
255:            }
256:
257:            /**
258:             * Method required by InputObject interface; in this class, it simply calls
259:             * setOnUserAction(c).  This is meant to be called by JCMPanel.gatherInputs().
260:             */
261:            public void notifyControllerOnChange(Controller c) {
262:                setOnUserAction(c);
263:            }
264:
265:            /**
266:             * Get the Controller that is notified when the user drags the point.  A null value means that
267:             * no notification is done.
268:             */
269:            public Controller getOnUserAction(Controller c) {
270:                return onUserAction;
271:            }
272:
273:            /**
274:             *  Move the point to (x,y), then "clamp" the value of x or y, if a clamp Value has been set.
275:             */
276:            public void setLocation(double x, double y) {
277:                xLoc = x;
278:                yLoc = y;
279:                xVar.setVariableValue(x);
280:                yVar.setVariableValue(y);
281:                xVar.serialNumber++;
282:                yVar.serialNumber++;
283:                checkClamp();
284:                needsRedraw();
285:            }
286:
287:            private void checkClamp() {
288:                // Apply the clamping values.
289:                if (clampX != null) {
290:                    xLoc = clampX.getVal();
291:                    xVar.setVariableValue(xLoc);
292:                } else if (clampY != null) {
293:                    yLoc = clampY.getVal();
294:                    yVar.setVariableValue(yLoc);
295:                }
296:            }
297:
298:            /**
299:             *  This method is required by the InputObject interface.  In this case, it just applies the
300:             *  clamping Values if any are specified.
301:             */
302:            public void checkInput() {
303:                xVar.needsClamp = true;
304:                yVar.needsClamp = true;
305:            }
306:
307:            /**
308:             *  This method, from the Drawable interface, draws the point.  It is not usually called directly.
309:             */
310:            public void draw(Graphics g, boolean coordsChanged) {
311:                if (coords == null)
312:                    return;
313:                checkPosition();
314:                if (useGhost)
315:                    g.setColor(getGhostColor());
316:                else
317:                    g.setColor(color);
318:                switch (style) {
319:                case DISK:
320:                    g.fillOval(xPosition - radius, yPosition - radius,
321:                            2 * radius + 1, 2 * radius + 1);
322:                    break;
323:                case SQUARE:
324:                    g.fillRect(xPosition - radius, yPosition - radius,
325:                            2 * radius + 1, 2 * radius + 1);
326:                    break;
327:                case CROSS:
328:                    g.drawLine(xPosition - radius, yPosition, xPosition
329:                            + radius, yPosition);
330:                    g.drawLine(xPosition, yPosition - radius, xPosition,
331:                            yPosition + radius);
332:                    break;
333:                }
334:            }
335:
336:            private void checkPosition() {
337:                // compute (xPosition, yPosition), the position where point is actually drawn
338:                useGhost = false;
339:                xVar.getVal(); // Forces recompute, if needsClamp
340:                yVar.getVal();
341:                if (Double.isNaN(xLoc) || Double.isNaN(yLoc)) {
342:                    if (xPosition == -10000) { // otherwise, use previous position
343:                        xPosition = coords.getLeft() + coords.getWidth() / 2;
344:                        yPosition = coords.getTop() + coords.getHeight() / 2;
345:                    }
346:                    useGhost = true;
347:                } else {
348:                    xPosition = coords.xToPixel(xLoc);
349:                    yPosition = coords.yToPixel(yLoc);
350:                }
351:                if (xPosition <= coords.getLeft()) {
352:                    useGhost = true;
353:                    xPosition = coords.getLeft() + 1;
354:                } else if (xPosition >= coords.getLeft() + coords.getWidth()) {
355:                    useGhost = true;
356:                    xPosition = coords.getLeft() + coords.getWidth() - 1;
357:                }
358:                if (yPosition <= coords.getTop()) {
359:                    useGhost = true;
360:                    yPosition = coords.getTop() + 1;
361:                } else if (yPosition >= coords.getTop() + coords.getHeight()) {
362:                    useGhost = true;
363:                    yPosition = coords.getTop() + coords.getHeight() - 1;
364:                }
365:            }
366:
367:            //------------------ Dragging the point ---------------------------
368:
369:            private boolean dragging; // True if the point is being dragged.
370:
371:            /**
372:             *  Check whether a mouse click (as specified in the MouseEvent parameter) is a 
373:             *  click on this DraggablePoint.  If so, return true, and start a drag operation.
374:             *  It is expected that the continueDrag() and finishDrag() will be called to
375:             *  complete the drag operation.  This is only meant to be called from
376:             *  the checkDraggables() method in class CoordinateRect.
377:             */
378:            public boolean startDrag(MouseEvent evt) {
379:                dragging = false;
380:                if (evt.isConsumed() || !getVisible() || coords == null)
381:                    return false;
382:                checkPosition();
383:                if (evt.getX() < xPosition - radius
384:                        || evt.getX() >= xPosition + radius
385:                        || evt.getY() < yPosition - radius
386:                        || evt.getY() >= yPosition + radius)
387:                    return false;
388:                dragging = true;
389:                evt.consume();
390:                return true;
391:            }
392:
393:            /**
394:             *  Continue a drag operation begun in startDrag().  This is not meant to be called directly.
395:             */
396:            public void continueDrag(MouseEvent evt) {
397:                if (!dragging)
398:                    return;
399:                int xInt = evt.getX();
400:                int yInt = evt.getY();
401:                double x = coords.pixelToX(evt.getX());
402:                double y = coords.pixelToY(evt.getY());
403:                if (x < coords.getXmin())
404:                    x = coords.getXmin();
405:                else if (x > coords.getXmax())
406:                    x = coords.getXmax();
407:                if (y < coords.getYmin())
408:                    y = coords.getYmin();
409:                else if (y > coords.getYmax())
410:                    y = coords.getYmax();
411:                setLocation(x, y);
412:                if (Double.isNaN(xLoc) || Double.isNaN(yLoc)) {
413:                    xPosition = xInt;
414:                    yPosition = yInt;
415:                }
416:                if (onUserAction != null)
417:                    onUserAction.compute();
418:            }
419:
420:            /**
421:             *  Finish a drag operation begun in startDrag().  This is not meant to be called directly.
422:             */
423:            public void finishDrag(MouseEvent evt) {
424:                dragging = false;
425:            }
426:
427:            private class DPV extends Variable implements  Tieable {
428:
429:                private boolean isXVar; // True for xVar; false for yVar.
430:
431:                long serialNumber; // This object's serial number.
432:                boolean needsClamp; // Set to true by DraggablePoint().checkInput().
433:
434:                DPV(boolean isXVar) {
435:                    // Create the variable.
436:                    super (isXVar ? "xDrag" : "yDrag");
437:                    this .isXVar = isXVar;
438:                    super .setVal(Double.NaN);
439:                }
440:
441:                public double getVal() {
442:                    // Return the value, after applying clamping, if necessary.
443:                    // (It's done this way because checkInput() can't use values of
444:                    // other objects, but after it's called, any call to getVal()
445:                    // should return the new correct value.)
446:                    if (needsClamp) {
447:                        if (isXVar) {
448:                            if (clampX != null) {
449:                                xLoc = clampX.getVal();
450:                                setVariableValue(xLoc);
451:                            }
452:                        } else {
453:                            if (clampY != null) {
454:                                yLoc = clampY.getVal();
455:                                setVariableValue(yLoc);
456:                            }
457:                        }
458:                        needsClamp = false;
459:                    }
460:                    return super .getVal();
461:                }
462:
463:                public void setVal(double val) {
464:                    // Set the value of the variable, and set the point's
465:                    // location to reflect new value.  (setLocation ups serial number
466:                    // and calls setVariableValue() to set the actual variable value.)
467:                    if (isXVar)
468:                        setLocation(val, yVar.getVal());
469:                    else
470:                        setLocation(xVar.getVal(), val);
471:                }
472:
473:                void setVariableValue(double val) {
474:                    // Call the setVal() routine from the superclass.
475:                    super .setVal(val);
476:                    needsClamp = false;
477:                }
478:
479:                public long getSerialNumber() {
480:                    // Return this Tieable object's serial number.
481:                    return serialNumber;
482:                }
483:
484:                public void sync(Tie tie, Tieable newest) {
485:                    // Synchronize values and serial numbers with newest.
486:                    if (!(newest instanceof  Value))
487:                        throw new IllegalArgumentException(
488:                                "Internal Error:  A MouseTracker variable can only be tied to a Value object.");
489:                    if (newest != this ) {
490:                        setVal(((Value) newest).getVal());
491:                        serialNumber = newest.getSerialNumber();
492:                    }
493:                }
494:
495:            }
496:
497:        } // end class DraggablePoint
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.