Source Code Cross Referenced for ExpressionInput.java in  » Science » jcm1-source » edu » hws » jcm » awt » 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.awt 
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.awt;
024:
025:        import edu.hws.jcm.data.*;
026:        import java.awt.*;
027:        import java.awt.event.*;
028:
029:        /**
030:         * An ExpressionInput is an input box that allows the user
031:         * input a mathematical expression.  There is an associated
032:         * object that belongs to the class Expression.  The
033:         * value of this object can change only when checkInput()
034:         * is called.  The checkInput() method is usually called by a Controller.
035:         *    <p>An ExpressionInput will ordinarily be registered with
036:         * a Controller in TWO ways:  It's added to a Controller
037:         * with the Controller's add() method.  This makes the Contrller
038:         * call the ExpressionInput's checkInput() method during the
039:         * Controller's compute() method.  Secondly, the Controller
040:         * is set as the "onUserAction" property.  This causes the
041:         * Controller's compute() method to be called when the user
042:         * presses return in the ExpressionInput box.  This is optional--
043:         * you might, for example, only want the Controller to compute()
044:         * when a Compute button is pressed.  You can also set the
045:         * ExpressionInput's onTextChange property to a Controller
046:         * if you want it to compute every time the text in the box
047:         * changes.
048:         *    <p>Use the function getFunction() if you want to
049:         * use an ExpressionInput as a way of inputting a function.
050:         *
051:         */
052:        public class ExpressionInput extends TextField implements  InputObject,
053:                Value {
054:
055:            /**
056:             * The Expression associate with this input box.  
057:             * Class EI is a private nested class.
058:             */
059:            protected EI expr;
060:
061:            /**
062:             * A parser for parsing the user's input
063:             * expression.  If this is null,
064:             * a default parser will be used and
065:             * only constant expressions will
066:             * be allowed.   
067:             */
068:            protected Parser parser;
069:
070:            //protected boolean hasChanged;
071:            protected String previousContents;
072:
073:            /**  
074:             * True if an error should be thrown
075:             * when checkInput() is called,
076:             * but the content of the box is not
077:             * a legal expression.  Otherwise, the
078:             * expression will become a constant
079:             * expression with value Double.NaN.   
080:             */
081:            protected boolean throwErrors;
082:
083:            private Controller onUserAction; // If this is non-null, the compute() method
084:            //   of onUserAction is called when the user
085:            //   presses return in this input-box.
086:
087:            private Controller onTextChange; // If this is non-null, the compute() method
088:            //   of onTextChange is called when the text
089:            //   in this input box changes
090:
091:            /**
092:             * Error message from the most recent
093:             * time the input was checked by a
094:             * call to checkInput().  If this is
095:             * null, then no error occurred.
096:             */
097:            protected String errorMessage;
098:
099:            private long serialNumber; // This goes up by one every time checkInput()
100:
101:            //   is called and finds a change in the
102:            //   user's input;
103:
104:            /**
105:             * Create a new ExpressionFunction with no associated parser.  This can only
106:             * be used to input constant expressions, unless you set a parser later with setParser().
107:             */
108:            public ExpressionInput() {
109:                this ("", null);
110:            }
111:
112:            /**
113:             * Create an ExpressionInputBox with initial contents given by initialValue.
114:             * (If initialValue is null, the empty string is used.)  If p is not null,
115:             * then p will be used to parse the contents of the box.
116:             *
117:             * @param initialValue initial contents of ExpressionInputBox.
118:             * @param p if non-null, this parser will be used to parse contents of the ExpressionInputBox.
119:             */
120:            public ExpressionInput(String initialValue, Parser p) {
121:                super (30);
122:                expr = new EI();
123:                if (initialValue == null)
124:                    initialValue = "";
125:                super .setText(initialValue);
126:                setBackground(Color.white);
127:                //enableEvents(KeyEvent.KEY_EVENT_MASK);
128:                setParser(p); // (Sets previousContents to null, so checkInput() will actually check the input.)
129:                checkInput(); // Won't throw an error, since throwErrors is false.
130:                throwErrors = true;
131:            }
132:
133:            /**   
134:             * Set the parser that is used to parse the user's input strings.
135:             * If this is null, then a default parser is used that will
136:             * only allow constant expressions.
137:             *
138:             * @param p parser to register with user's input strings.
139:             */
140:            public void setParser(Parser p) {
141:                parser = (p == null) ? new Parser() : p;
142:                //hasChanged = true;  // force re-compute when checkInput() is next called.
143:                previousContents = null;
144:            }
145:
146:            /**
147:             * Get the Expression associated with this ExpressionInput.
148:             *
149:             */
150:            public Expression getExpression() {
151:                return expr;
152:            }
153:
154:            /**      
155:             * Get a function of one variable whose value at a real number
156:             * x is computed by assigning x to the variable v and then
157:             * returning the value of the expression associated with this
158:             * ExpressionInput.  Of couse, v should be one of the variables
159:             * registered with the Parser for this ExpressionInput, or else
160:             * in can never occur in the expression.
161:             *    Note that the value of the variable v changes TEMPORARILY
162:             * when the function is evaluated.  (So you should not use
163:             * a variable where setting the value has a side effect,
164:             * such as the variable associated with a SliderVariable.)
165:             *
166:             * @param v The function that is returned in a function of this variable.
167:             */
168:            public Function getFunction(Variable v) {
169:                return new SimpleFunction(expr, v);
170:            }
171:
172:            /**
173:             * Get a function of one or more variables whose value at arguments
174:             * x1, x2, ... is computed by assigning the x's to the variables and then
175:             * returning the value of the expression associated with this
176:             * ExpressionInput.  Of couse, each v[i] should be one of the variables
177:             * registered with the Parser for this ExpressionInput.
178:             *    Note that the value of the variables change TEMPORARILY
179:             * when the function is evaluated.
180:             *
181:             * @param v The function that is returned is a function of the variables in this array.
182:             */
183:            public Function getFunction(Variable[] v) {
184:                return new SimpleFunction(expr, v);
185:            }
186:
187:            /**      
188:             * Return the current value of the expression associated with
189:             * this ExpressionInput.
190:             */
191:            public double getVal() {
192:                return expr.getVal();
193:            }
194:
195:            /**   
196:             * If the parameter c is non-null, then its compute method will be called whenever
197:             * the user presses the return key while typing in this text-input box.
198:             */
199:            public void setOnUserAction(Controller c) {
200:                onUserAction = c;
201:                enableEvents(AWTEvent.ACTION_EVENT_MASK);
202:            }
203:
204:            /**   
205:             * Return the Controller, if any, that is notified when the user 
206:             * presses return in this text-input box.
207:             */
208:            public Controller getOnUserAction() {
209:                return onUserAction;
210:            }
211:
212:            /**
213:             * Method required by InputObject interface; in this class, it simply calls
214:             * setOnUserAction(c).  This is meant to be called by JCMPanel.gatherInputs().
215:             */
216:            public void notifyControllerOnChange(Controller c) {
217:                setOnUserAction(c);
218:            }
219:
220:            /**   
221:             * If the parameter, c, is non-null, then its compute method will be called whenever
222:             * the text in this input box changes.  Furthermore, the throwErrors
223:             * property will be set to false, to avoid throwing multiple errors
224:             * while the user is typing.  (You can change it back to true if
225:             * you want by calling setThrowErrors(true).)  It would only rarely make sense to
226:             * use this feature.
227:             */
228:            public void setOnTextChange(Controller c) {
229:                onTextChange = c;
230:                enableEvents(AWTEvent.TEXT_EVENT_MASK);
231:                if (c != null)
232:                    throwErrors = false;
233:            }
234:
235:            /**
236:             * Return the Controller, if any, that is notified whenever the text
237:             * in this input box changes
238:             */
239:            public Controller getOnTextChange() {
240:                return onTextChange;
241:            }
242:
243:            /**   
244:             * Set the throwErrors property.  When this is true, a JCMError can be thrown
245:             * when checkInput() is called an a parse error is found in the contents of the input box.
246:             * If throwErrors is false, no error is thrown.  Instead,
247:             * the expression is set to a constant expression with value Double.NaN.
248:             */
249:            public void setThrowErrors(boolean throwErrors) {
250:                this .throwErrors = throwErrors;
251:            }
252:
253:            /**
254:             * Return the value of the throwErrors property, which determines whether errors
255:             * can be thrown when checkInput() is called.
256:             */
257:            public boolean getThrowErrors() {
258:                return throwErrors;
259:            }
260:
261:            /**   
262:             * Get error message from previous call to checkInput().
263:             * Returns null if and only if there was no error.
264:             */
265:            public String getErrorMessage() {
266:                return errorMessage;
267:            }
268:
269:            //---------------- Some implementation details -------------------------------------------------
270:
271:            /**      
272:             * Get the expression from the box, maybe throw a JBCError
273:             * if a ParseError occurs.  This is meant to be called by a Controller, in general.
274:             * The expression associated with this ExpressionInput can only change when this
275:             * method is called; it DOES NOT change continuously as the user types.
276:             */
277:            public void checkInput() {
278:                boolean hasChanged = previousContents == null
279:                        || !previousContents.equals(getText());
280:                if (!hasChanged)
281:                    return;
282:                expr.serialNumber++;
283:                String contents = getText();
284:                try {
285:                    expr.exp = parser.parse(contents);
286:                    errorMessage = null;
287:                    previousContents = getText();
288:                } catch (ParseError e) {
289:                    expr.exp = null;
290:                    if (throwErrors) {
291:                        errorMessage = "Error in expression: " + e.getMessage();
292:                        setCaretPosition(e.context.pos);
293:                        requestFocus();
294:                        throw new JCMError(e.getMessage(), this );
295:                    } else
296:                        errorMessage = "Error in expression at position "
297:                                + e.context.pos + ": " + e.getMessage();
298:                }
299:            }
300:
301:            /**   
302:             * Set the text displayed in this input box.  This overrides TextField.setText 
303:             * to make sure that the expression will be recomputed the next time
304:             * checkInput() is called.   
305:             */
306:            public void setText(String str) {
307:                super .setText(str);
308:                //hasChanged = true;
309:                previousContents = null;
310:            }
311:
312:            /**
313:             * Override processKeyEvent to only allow characters
314:             * that are legal in expressions. This is not meant to be called directly. 
315:             
316:            public void processKeyEvent(KeyEvent evt) {
317:               if (evt.getID() == KeyEvent.KEY_PRESSED) {
318:                  int ch = evt.getKeyCode();
319:                  char chr = evt.getKeyChar();
320:                  boolean use = (chr != 0 && (Character.isDigit(chr) || Character.isLetter(chr))
321:                                     || chr == '.' || chr == '(' || chr == ')'
322:                                     || chr == '-' || chr == '+' || chr == '*'
323:                                     || chr == '/' || chr == '^' || chr == ','
324:                                     || chr == ':' || chr == '?' || chr == '|'
325:                                     || chr == '&' || chr == '~' || chr == '='
326:                                     || chr == '<' || chr == '>' || chr == '!')
327:                                     || ch == KeyEvent.VK_DELETE || ch == KeyEvent.VK_SPACE 
328:                                     || ch == KeyEvent.VK_BACK_SPACE;
329:                  boolean useControl = use || ch == KeyEvent.VK_TAB 
330:                                           || ch ==KeyEvent.VK_ENTER || chr == 0;
331:                  if (!useControl) {
332:                     evt.consume();
333:                     Toolkit.getDefaultToolkit().beep();
334:                  }
335:                  else if (use)
336:                     hasChanged = true;
337:               }
338:               super.processKeyEvent(evt);
339:            }
340:             */
341:
342:            /**
343:             * Overridden to call onUserAction.compute() if onUserAction is non-null.
344:             * This is not meant to be called directly
345:             */
346:            public void processActionEvent(ActionEvent evt) {
347:                if (onUserAction != null)
348:                    onUserAction.compute();
349:                super .processActionEvent(evt);
350:            }
351:
352:            /**  
353:             * Overridden to call onUserAction.compute() if onUserAction is non-null.
354:             * This is not meant to be called directly.
355:             */
356:            public void processTextEvent(TextEvent evt) {
357:                if (onTextChange != null)
358:                    onTextChange.compute();
359:                super .processTextEvent(evt);
360:            }
361:
362:            /**   
363:             * The expression associated with an ExpressionInput belongs to this class.
364:             * So is any derivative of such a function.  Note that derivatives
365:             * must be recomputed when the expression changes.  This is done
366:             * via "lazy evaluation", that is, only when necessary.  When
367:             * a derivative is used, it tests whether it is out of date
368:             * by comparing its serialNumber to the serial number of the
369:             * expression that it is the derivative of.  If they don't match,
370:             * then the expression is recomputed and the serial number is updated.
371:             * The serial number and defintion of the main expresssion is changed by
372:             * checkInput() whenever the user's input has changed.
373:             */
374:            protected class EI implements  Expression {
375:                /**
376:                 * The actual expression, or null if the
377:                 * expression is undefined.  If this is a
378:                 * derivative of another EI, this will be
379:                 * recomputed as necessary when the expression is used
380:                 * in some way.
381:                 */
382:                ExpressionProgram exp;
383:
384:                /**
385:                 * This is null for the original expression input by the
386:                 * user.  If this EI was formed by taking the derivative
387:                 * of anotehr EI, that EI is stored here. 
388:                 */
389:                EI derivativeOf;
390:
391:                /**
392:                 * Which Variable is this a derivative with respect to?
393:                 * If derivativeOf is null, so is wrt.      
394:                 */
395:                Variable wrt;
396:
397:                /**
398:                 * For the original expression input by the user, this
399:                 * goes up by one each time checkInput() is called and
400:                 * finds a change in the user's input.  For derivative 
401:                 * EI, this is the serial number of "derivativeOf" at
402:                 * the time this derivative expression was last computed.      
403:                 */
404:                int serialNumber;
405:
406:                EI() {
407:                    serialNumber = -1; // Forces exp to be computed the first time it is needed.
408:                }
409:
410:                public double getVal() {
411:                    checkForChanges();
412:                    if (exp == null)
413:                        return Double.NaN;
414:                    return exp.getVal();
415:                }
416:
417:                public double getValueWithCases(Cases c) {
418:                    checkForChanges();
419:                    if (exp == null)
420:                        return Double.NaN;
421:                    return exp.getValueWithCases(c);
422:                }
423:
424:                public String toString() {
425:                    checkForChanges();
426:                    if (exp == null)
427:                        return "(undefined)";
428:                    return exp.toString();
429:                }
430:
431:                public Expression derivative(Variable wrt) {
432:                    EI deriv = new EI();
433:                    deriv.derivativeOf = this ;
434:                    deriv.wrt = wrt;
435:                    return deriv;
436:                }
437:
438:                public boolean dependsOn(Variable x) {
439:                    checkForChanges();
440:                    return exp.dependsOn(x);
441:                }
442:
443:                void checkForChanges() {
444:                    if (derivativeOf != null) {
445:                        derivativeOf.checkForChanges();
446:                        if (serialNumber != derivativeOf.serialNumber) {
447:                            serialNumber = derivativeOf.serialNumber;
448:                            if (errorMessage != null)
449:                                exp = null;
450:                            else
451:                                exp = (ExpressionProgram) derivativeOf.exp
452:                                        .derivative(wrt);
453:                        }
454:                    }
455:                }
456:            } // end nested class EI
457:
458:        } // end class ExpressionInput
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.