Source Code Cross Referenced for TableFunctionGraph.java in  » Science » jcm1-source » edu » hws » jcm » functions » 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.functions 
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.functions;
024:
025:        import java.awt.*;
026:        import java.awt.event.*;
027:        import edu.hws.jcm.data.*;
028:        import edu.hws.jcm.awt.*;
029:        import edu.hws.jcm.draw.*;
030:
031:        /**
032:         *  A TableFunctionGraph is a Drawable object that can be added to a CoordinateRect (or DisplayCanvas).
033:         *  It draws the graph of a specified TableFunction.
034:         *  A TableFunction is a function and can also be graphed by an object of the class edu.hws.jcm.draw.Graph1D.
035:         *  However, a TableFunctionGraph offers the option of showing the points from the table that defines
036:         *  the function as small disks (true by default) and the option of making the graph "interactive" so 
037:         *  that the user can drag the points (false by default).
038:         */
039:        public class TableFunctionGraph extends Drawable implements 
040:                MouseListener, MouseMotionListener {
041:
042:            private TableFunction function; // The function that is drawn.
043:            private boolean showPoints; // Are the points from the table shown as little disks?
044:            private boolean interactive; // Can user drag points?
045:            private Computable onDrag; // If interactive is true and onDrag is not null, then this
046:            //  Computable's compute() method is called each time a
047:            //  point moves as the user drags it.
048:            private Computable onFinishDrag; // If interactive is true and onFinishDraw is not null, then this
049:            //  Computable's compute() method is called when the user
050:            //  finishes a drag operation (if the point is actually moved).
051:            private Color color; // non-null color of the graph.
052:
053:            /**
054:             * Create a TableFunctionGraph that initially draws no function.  A function can be set
055:             * later with setFunction.
056:             */
057:            public TableFunctionGraph() {
058:                this (null);
059:            }
060:
061:            /**
062:             * Create a TableFunctionGraph to draw the specified TableFunction.
063:             */
064:            public TableFunctionGraph(TableFunction function) {
065:                this .function = function;
066:                this .color = Color.magenta;
067:                showPoints = true;
068:            }
069:
070:            /**
071:             *  Set the function whose graph is drawn by this TableFunctionGraph.  If the value is null,
072:             *  nothing is drawn
073:             */
074:            public void setFunction(TableFunction function) {
075:                this .function = function;
076:                needsRedraw();
077:            }
078:
079:            /**
080:             *  Get the TableFunction whose graph is drawn by this TableFunctionGraph.  If the value is null,
081:             *  then no graph is drawn.
082:             */
083:            public TableFunction getFunction() {
084:                return function;
085:            }
086:
087:            /**
088:             * Specify a controller whose compute() method will be called repeatedly
089:             * as the user drags one of the points from the table function.  This only
090:             * applies if the "interactive" property is true.
091:             */
092:            public void setOnDrag(Computable c) {
093:                onDrag = c;
094:            }
095:
096:            /**
097:             * Get the Computable that is notified as the user drags a point.
098:             */
099:            public Computable getOnDrag() {
100:                return onDrag;
101:            }
102:
103:            /**
104:             * Specify a controller whose compute() method will be called once
105:             * when the user finishes dragging one of the points from the table function.
106:             * This only applies if the "interactive" property is true.
107:             */
108:            public void setOnFinishDrag(Computable c) {
109:                onFinishDrag = c;
110:            }
111:
112:            /**
113:             * Get the Computable that is notified when the user finishes dragging a point.
114:             */
115:            public Computable getOnFinishDrag() {
116:                return onFinishDrag;
117:            }
118:
119:            /**
120:             *  Set the value of the interactive property, which is true if the user can
121:             *  modify the function by dragging the points from the table.  The default is false.
122:             */
123:            public void setInteractive(boolean interactive) {
124:                if (this .interactive == interactive)
125:                    return;
126:                if (this .interactive && canvas != null) {
127:                    canvas.removeMouseListener(this );
128:                    canvas.removeMouseMotionListener(this );
129:                }
130:                this .interactive = interactive;
131:                if (this .interactive && canvas != null) {
132:                    canvas.addMouseListener(this );
133:                    canvas.addMouseMotionListener(this );
134:                }
135:            }
136:
137:            /**
138:             *  Get the value of the interactive property, which is true if the user can
139:             *  modify the function by dragging the points from the table.
140:             */
141:            public boolean getInteractive() {
142:                return interactive;
143:            }
144:
145:            /**
146:             *  Set the showPoints property, which determines whether the points
147:             *  from the table that defines the function are visible as little
148:             *  disks.  The default is true;
149:             */
150:            public void setShowPoints(boolean show) {
151:                showPoints = show;
152:                needsRedraw();
153:            }
154:
155:            /**
156:             *  Get the showPoints property, which determines whether the points
157:             *  from the table that defines the function are visible as little
158:             *  disks.
159:             */
160:            public boolean getShowPoints() {
161:                return showPoints;
162:            }
163:
164:            /**
165:             * Set the color that is used for drawing the graph.  The defalt is magenta.
166:             * If the specified Color value is null, the call to setColor is ignored.
167:             */
168:            public void setColor(Color c) {
169:                if (c != null) {
170:                    color = c;
171:                    needsRedraw();
172:                }
173:            }
174:
175:            /** 
176:             *  Get the non-null color that is used for drawing the graph.
177:             */
178:            public Color getColor() {
179:                return color;
180:            }
181:
182:            /**
183:             * Sets the values of member variables canvas and coords.  This is
184:             * designed to be called only by the CoordinateRect class.  This overrides
185:             * Drawable.setOwnerData();
186:             */
187:            protected void setOwnerData(DisplayCanvas canvas,
188:                    CoordinateRect coords) {
189:                if (interactive && this .canvas != null) {
190:                    canvas.removeMouseListener(this );
191:                    canvas.removeMouseMotionListener(this );
192:                }
193:                super .setOwnerData(canvas, coords);
194:                if (interactive && this .canvas != null) {
195:                    canvas.addMouseListener(this );
196:                    canvas.addMouseMotionListener(this );
197:                }
198:            }
199:
200:            /**
201:             *  Provided as a convenience.  If the function for this TableFunctionGraph is non-null,
202:             *  its style is set to the specified style, and the graph is redrawn.  The parameter
203:             *  should be one of the constants TableFunction.SMOOTH, TableFunction.PIECEWISE_LINEAR,
204:             *  TableFunction.STEP, TableFunction.STEP_LEFT, or TableFunction.STEP_RIGHT.
205:             */
206:            public void setFunctionStyle(int style) {
207:                if (function != null && function.getStyle() != style) {
208:                    function.setStyle(style);
209:                    needsRedraw();
210:                }
211:            }
212:
213:            /**
214:             * Override the draw() method from class Drawable to draw the function.
215:             * This is not meant to be called directly.
216:             */
217:            public void draw(Graphics g, boolean coordsChanged) {
218:                if (function == null || coords == null)
219:                    return;
220:                int ct = function.getPointCount();
221:                if (ct == 0)
222:                    return;
223:                int startPt; // The index of first point from the table that we have to consider
224:                int endPt; // The index of the last point from the table that we have to consider
225:                double xmin = coords.pixelToX(coords.getLeft());
226:                double xmax = coords.pixelToX(coords.getLeft()
227:                        + coords.getWidth());
228:                if (function.getX(0) > xmax || function.getX(ct - 1) < xmin)
229:                    return;
230:                startPt = 0;
231:                while (startPt < ct - 1 && function.getX(startPt + 1) <= xmin)
232:                    startPt++;
233:                endPt = ct - 1;
234:                while (endPt > 1 && function.getX(endPt - 1) >= xmax)
235:                    endPt--;
236:                double x, y, a, b; // usually, two consecutive points on curve
237:                int xInt, yInt, aInt, bInt; // usually, pixel coordinates for the two points.
238:                g.setColor(color);
239:                switch (function.getStyle()) {
240:                case TableFunction.SMOOTH: {
241:                    if (endPt > startPt) {
242:                        x = function.getX(startPt);
243:                        y = function.getVal(x);
244:                        xInt = coords.xToPixel(x);
245:                        yInt = coords.yToPixel(y);
246:                        double limit = xmax;
247:                        if (function.getX(endPt) < limit)
248:                            limit = function.getX(endPt);
249:                        coords.xToPixel(function.getX(ct - 1));
250:                        aInt = xInt;
251:                        while (x < limit) {
252:                            aInt += 3;
253:                            a = coords.pixelToX(aInt);
254:                            if (a > limit)
255:                                a = limit;
256:                            b = function.getVal(a);
257:                            bInt = coords.yToPixel(b);
258:                            g.drawLine(xInt, yInt, aInt, bInt);
259:                            x = a;
260:                            xInt = aInt;
261:                            yInt = bInt;
262:                        }
263:                    }
264:                    break;
265:                }
266:                case TableFunction.PIECEWISE_LINEAR: {
267:                    x = function.getX(startPt);
268:                    xInt = coords.xToPixel(x);
269:                    y = function.getY(startPt);
270:                    yInt = coords.yToPixel(y);
271:                    for (int i = startPt + 1; i <= endPt; i++) {
272:                        a = function.getX(i);
273:                        aInt = coords.xToPixel(a);
274:                        b = function.getY(i);
275:                        bInt = coords.yToPixel(b);
276:                        g.drawLine(xInt, yInt, aInt, bInt);
277:                        xInt = aInt;
278:                        yInt = bInt;
279:                    }
280:                    break;
281:                }
282:                case TableFunction.STEP: {
283:                    x = function.getX(startPt);
284:                    xInt = coords.xToPixel(x);
285:                    for (int i = startPt; i <= endPt; i++) {
286:                        if (i < endPt) {
287:                            double nextX = function.getX(i + 1);
288:                            a = (x + nextX) / 2;
289:                            x = nextX;
290:                        } else
291:                            a = x;
292:                        aInt = coords.xToPixel(a);
293:                        y = function.getY(i);
294:                        yInt = coords.yToPixel(y);
295:                        g.drawLine(xInt, yInt, aInt, yInt);
296:                        xInt = aInt;
297:                    }
298:                    break;
299:                }
300:                case TableFunction.STEP_LEFT: {
301:                    x = function.getX(startPt);
302:                    xInt = coords.xToPixel(x);
303:                    for (int i = startPt + 1; i <= endPt; i++) {
304:                        a = function.getX(i);
305:                        aInt = coords.xToPixel(a);
306:                        y = function.getY(i - 1);
307:                        yInt = coords.yToPixel(y);
308:                        g.drawLine(xInt, yInt, aInt, yInt);
309:                        xInt = aInt;
310:                    }
311:                    break;
312:                }
313:                case TableFunction.STEP_RIGHT: {
314:                    x = function.getX(startPt);
315:                    xInt = coords.xToPixel(x);
316:                    for (int i = startPt + 1; i <= endPt; i++) {
317:                        a = function.getX(i);
318:                        aInt = coords.xToPixel(a);
319:                        y = function.getY(i);
320:                        yInt = coords.yToPixel(y);
321:                        g.drawLine(xInt, yInt, aInt, yInt);
322:                        xInt = aInt;
323:                    }
324:                    break;
325:                }
326:                }
327:                if (!showPoints)
328:                    return;
329:                for (int i = startPt; i <= endPt; i++) {
330:                    x = function.getX(i);
331:                    y = function.getY(i);
332:                    xInt = coords.xToPixel(x);
333:                    yInt = coords.yToPixel(y);
334:                    g.fillOval(xInt - 2, yInt - 2, 5, 5);
335:                }
336:            } // end draw();
337:
338:            //-------------------- Dragging --------------------------
339:
340:            private int dragPoint = -1; // -1 if no point is being dragged;
341:            // Otherwise, the index of the point being dragged.
342:
343:            private int startX, startY; // Point where mouse was clicked at start of drag.
344:
345:            private int prevY; // Previous position of mouse during dragging.
346:
347:            private boolean moved; // Becomes true once the clicked point has actually
348:
349:            // been dragged a bit.  If the mouse is released before
350:            // the point is moved at least 3 pixels, then the associated 
351:            // y-value is not changed.
352:
353:            /**
354:             * Method required by the MouseListener interface.  Defined here to
355:             * support dragging of points on the function's graph.  Not meant to be called directly.
356:             */
357:            public void mousePressed(MouseEvent evt) {
358:                dragPoint = -1;
359:                if (function == null || getVisible() == false || canvas == null
360:                        || coords == null || evt.isConsumed())
361:                    return;
362:                if (evt.isShiftDown() || evt.isMetaDown()
363:                        || evt.isControlDown() || evt.isAltDown())
364:                    return;
365:                moved = false;
366:                int ct = function.getPointCount();
367:                for (int i = 0; i < ct; i++) {
368:                    int x = coords.xToPixel(function.getX(i));
369:                    int y = coords.yToPixel(function.getY(i));
370:                    if (evt.getX() >= x - 3 && evt.getX() <= x + 3
371:                            && evt.getY() >= y - 3 && evt.getY() <= y + 3) {
372:                        startX = evt.getX();
373:                        prevY = startY = evt.getY();
374:                        dragPoint = i;
375:                        evt.consume();
376:                        return;
377:                    }
378:                }
379:            }
380:
381:            /**
382:             * Method required by the MouseListener interface.  Defined here to
383:             * support dragging of points on the function's graph.  Not meant to be called directly.
384:             */
385:            public void mouseReleased(MouseEvent evt) {
386:                if (dragPoint == -1)
387:                    return;
388:                evt.consume();
389:                if (!moved) {
390:                    dragPoint = -1;
391:                    return;
392:                }
393:                mouseDragged(evt);
394:                dragPoint = -1;
395:                if (onFinishDrag != null)
396:                    onFinishDrag.compute();
397:            }
398:
399:            /**
400:             * Method required by the MouseListener interface.  Defined here to
401:             * support dragging of points on the function's graph.  Not meant to be called directly.
402:             */
403:            public void mouseDragged(MouseEvent evt) {
404:                if (dragPoint == -1 || prevY == evt.getY())
405:                    return;
406:                evt.consume();
407:                if (!moved && Math.abs(evt.getY() - startY) < 3)
408:                    return;
409:                moved = true;
410:                int y = evt.getY();
411:                if (y < coords.getTop() + 4)
412:                    y = coords.getTop() + 4;
413:                else if (y > coords.getTop() + coords.getHeight() - 4)
414:                    y = coords.getTop() + coords.getHeight() - 4;
415:                if (Math.abs(evt.getX() - startX) > 72)
416:                    y = startY;
417:                if (y == prevY)
418:                    return;
419:                prevY = y;
420:                function.setY(dragPoint, coords.pixelToY(prevY));
421:                needsRedraw();
422:                if (onDrag != null)
423:                    onDrag.compute();
424:            }
425:
426:            /**
427:             * Empty method, required by the MouseListener interface.
428:             */
429:            public void mouseClicked(MouseEvent evt) {
430:            }
431:
432:            /**
433:             * Empty method, required by the MouseMotionListener interface.
434:             */
435:            public void mouseEntered(MouseEvent evt) {
436:            }
437:
438:            /**
439:             * Empty method, required by the MouseMotionListener interface.
440:             */
441:            public void mouseExited(MouseEvent evt) {
442:            }
443:
444:            /**
445:             * Empty method, required by the MouseMotionListener interface.
446:             */
447:            public void mouseMoved(MouseEvent evt) {
448:            }
449:
450:        } // end class TableFunctionGraph
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.