Subversion Repositories wimsdev

Rev

Rev 3653 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*************************************************************************
  2. *                                                                        *
  3. *  This source code file, and compiled classes derived from it, can      *
  4. *  be used and distributed without restriction, including for commercial *
  5. *  use.  (Attribution is not required but is appreciated.)               *
  6. *                                                                        *
  7. *   David J. Eck                                                         *
  8. *   Department of Mathematics and Computer Science                       *
  9. *   Hobart and William Smith Colleges                                    *
  10. *   Geneva, New York 14456,   USA                                        *
  11. *   Email: eck@hws.edu          WWW: http://math.hws.edu/eck/            *
  12. *                                                                        *
  13. *************************************************************************/
  14.  
  15. import edu.hws.jcm.awt.*;
  16. import edu.hws.jcm.data.*;
  17. import edu.hws.jcm.draw.*;
  18. import edu.hws.jcm.functions.*;
  19.  
  20. import java.awt.*;
  21. import java.awt.event.*;
  22. import java.util.StringTokenizer;
  23. import java.applet.Applet;
  24.  
  25. /**
  26.  * An Evaluator applet lets the user enter the values of one or more variables,
  27.  * and it displayes the values of one or more expressions that can involve those
  28.  * variables.  The expression values are updated continuously as the user types.
  29.  */
  30.  
  31. public class Evaluator extends Applet implements ActionListener {
  32.  
  33.    private Frame frame;       // If non-null, a separate window.
  34.    private String frameTitle; // Title for the separate window.
  35.    private Button launchButton;  // If non-null, then clicking this buttons opens a separate window.
  36.    private String launchButtonName;  // Name for the launch button.
  37.  
  38.    /**
  39.     * The init() method is called by the system to set up the applet.
  40.     * If the applet does not appear as a button, then init() creates the main panel of the applet
  41.     * and calls setUpMainPanel to set it up.
  42.     */
  43.    public void init() {
  44.       frameTitle = getParameter("FrameTitle"); // Get title to be used for separate window, if any.
  45.       if (frameTitle == null) {
  46.          frameTitle = "Calculator";
  47.          int pos = frameTitle.lastIndexOf('.');
  48.          if (pos > -1)
  49.             frameTitle =  frameTitle.substring(pos+1);
  50.       }
  51.       setLayout(new BorderLayout());
  52.       int height = getSize().height;
  53.       launchButtonName = getParameter("LaunchButtonName");
  54.       if ( (height > 0 && height <= 35) || launchButtonName != null) {
  55.               // Use a separater window and only show a button in the applet.
  56.           if (launchButtonName == null)
  57.                launchButtonName = "Launch " + frameTitle;
  58.           launchButton = new Button(launchButtonName);
  59.           add(launchButton, BorderLayout.CENTER);
  60.           launchButton.addActionListener(this);
  61.       }
  62.       else {
  63.              // Show the main panel in the applet, not in a separate window.
  64.           add(makeMainPanel(), BorderLayout.CENTER);
  65.       }
  66.    }
  67.  
  68.    /*
  69.     * Create the main panel of the applet.
  70.     */
  71.    public JCMPanel makeMainPanel() {
  72.    
  73.       // Get values of color params.
  74.      
  75.       Color background = getColorParam("BackgroundColor", Color.gray);
  76.       Color labelBackground = getColorParam("LabelBackground", new Color(225,225,225));
  77.       Color labelForeground = getColorParam("LabelForeground", new Color(0,0,200));
  78.       Color answerBackground = getColorParam("AnswerBackground", labelBackground);
  79.       Color answerForeground = getColorParam("AnswerForeground", Color.red);
  80.       Color inputBackground = getColorParam("InputBackground", Color.white);
  81.       Color inputForeground = getColorParam("InputForeground", Color.black);
  82.  
  83.       // Create the panel and subpanel.  The left subpanel will hold labes for the
  84.       // variables and expressions.  The right subpanel will hold the variable input
  85.       // boxes and expression values.
  86.  
  87.       JCMPanel panel = new JCMPanel(5);
  88.       panel.setBackground(background);
  89.       panel.setInsetGap(3);
  90.       setLayout(new BorderLayout());
  91.       add(panel,BorderLayout.CENTER);
  92.       JCMPanel left = new JCMPanel(0,1,3);
  93.       panel.add(left, BorderLayout.CENTER);
  94.       JCMPanel right = new JCMPanel(0,1,3);
  95.       panel.add(right, BorderLayout.EAST);
  96.      
  97.       // Create a parser and configure it to allow factorials and summations.
  98.      
  99.       Parser parser = new Parser();
  100.       parser.addOptions(Parser.FACTORIAL);
  101.       parser.add( new SummationParser() );
  102.      
  103.       // Create the variable input boxes, using variable names given by
  104.       // applet parameters.  If no names are provided in applet parameters,
  105.       // use one variable named "x".  Add the Variables from the variable inputs
  106.       // to the parser so that they can be used in expressions.
  107.      
  108.       int ct = 0;
  109.       String variableName = getParameter("Variable");
  110.       if (variableName == null) {
  111.          variableName = getParameter("Variable1");
  112.          if (variableName == null) {
  113.             variableName = "x";
  114.          }
  115.          else
  116.             ct = 1;
  117.       }
  118.       String firstVar = variableName;
  119.       while (variableName != null) {
  120.          String valString = "0";
  121.          variableName = variableName.trim();
  122.          int pos = variableName.indexOf(" ");
  123.          if (pos > 0) {
  124.                 // If there is anything in the string after the variable name, use it as the variable value.
  125.              valString = variableName.substring(pos+1).trim();
  126.              variableName = variableName.substring(0,pos);
  127.          }
  128.          Label lab = new Label(" Input:  " + variableName + " =  ", Label.RIGHT);
  129.          lab.setBackground(labelBackground);
  130.          lab.setForeground(labelForeground);
  131.          left.add(lab);
  132.          VariableInput v = new VariableInput(variableName,valString,parser);
  133.          v.setBackground(inputBackground);
  134.          v.setForeground(inputForeground);
  135.          v.setThrowErrors(false);
  136.          v.setOnTextChange(panel.getController());
  137.          v.setOnUserAction(panel.getController());
  138.          right.add(v);
  139.          ct++;
  140.          variableName = getParameter("Variable" + ct);
  141.       }
  142.      
  143.       // Get the expressions to be evalueated from applet parameters and add evaluators
  144.       // to the applet.  If not expressions are provided in applet parameters, use
  145.       // one expression, "log2(x)".
  146.      
  147.       ct = 0;
  148.       String function = getParameter("Expression");
  149.       if (function == null) {
  150.          function = getParameter("Expression1");
  151.          if (function == null)
  152.             function = "log2(" + firstVar + ")";
  153.          else
  154.             ct = 1;
  155.       }
  156.       while (function != null) {
  157.          Label lab = new Label(" " + function + " =  ", Label.RIGHT);
  158.          lab.setBackground(labelBackground);
  159.          lab.setForeground(labelForeground);
  160.          left.add(lab);
  161.          try {
  162.             DisplayLabel d = new DisplayLabel("#", parser.parse(function));
  163.             d.setBackground(answerBackground);
  164.             d.setForeground(answerForeground);
  165.             d.setAlignment(Label.CENTER);
  166.             right.add(d);
  167.          }
  168.          catch (ParseError e) {
  169.             right.add(new Label("invalid function"));
  170.          }
  171.          ct++;
  172.          function = getParameter("Expression" + ct);
  173.       }
  174.      
  175.       return panel;
  176.  
  177.    } // end makeMainPanel()
  178.    
  179.  
  180.    /**
  181.     *  Respond when user clicks a button; not meant to be called directly.
  182.     *  This opens and closes the separate window.
  183.     */
  184.    synchronized public void actionPerformed(ActionEvent evt) {
  185.       Object source = evt.getSource();
  186.       if (source == launchButton && launchButton != null) {
  187.          launchButton.setEnabled(false);
  188.          if (frame == null) {
  189.             frame = new Frame(frameTitle);
  190.             frame.add(makeMainPanel());
  191.             frame.addWindowListener( new WindowAdapter() {
  192.                   public void windowClosing(WindowEvent evt) {
  193.                      frame.dispose();
  194.                   }
  195.                   public void windowClosed(WindowEvent evt) {
  196.                      frameClosed();
  197.                   }
  198.                } );
  199.             frame.pack();
  200.             frame.setLocation(50,50);
  201.             frame.setVisible(true);
  202.             launchButton.setLabel("Close Window");
  203.             launchButton.setEnabled(true);
  204.          }
  205.          else {
  206.             frame.dispose();
  207.          }
  208.       }
  209.    }
  210.    
  211.    synchronized private void frameClosed() {
  212.         // respond when separate window closes.
  213.       frame = null;
  214.       launchButton.setLabel(launchButtonName);
  215.       launchButton.setEnabled(true);
  216.    }
  217.    
  218.    /**
  219.     * Get The value of an applet parameter that specifies a color.  The color can be specfied
  220.     * as a list of three numbers in the range 0 to 255 or by one of the standard color names
  221.     * ("black", "red", "blue", "green", "yellow", "cyan", "magenta", "gray", "darkgray",
  222.     * "lightgray", "pink", "orange", "white").  Color names are not case sensitive.
  223.     *
  224.     * @param paramName The name of the applet parameter.
  225.     * @param defaultColor The value to be returned if getParameter(paramName) is null or is not a valid color.
  226.     */
  227.    protected Color getColorParam(String paramName, Color defaultColor) {
  228.       String data = getParameter(paramName);
  229.       if (data == null || data.trim().length() == 0)
  230.          return defaultColor;
  231.       data = data.trim();
  232.       if (Character.isLetter(data.charAt(0))) {
  233.          for (int i = 0; i < colorNames.length; i++)
  234.             if (data.equalsIgnoreCase(colorNames[i]))
  235.                return colors[i];
  236.          return defaultColor;
  237.       }
  238.       else {
  239.          StringTokenizer tokenizer = new StringTokenizer(data," \t,;");
  240.          int count = tokenizer.countTokens();
  241.          if (count < 3)
  242.             return defaultColor;
  243.          double[] nums = new double[3];
  244.          for (int i = 0; i < 3; i++) {
  245.             try {
  246.                Double d = new Double(tokenizer.nextToken());
  247.                nums[i] = d.doubleValue();
  248.             }
  249.             catch (NumberFormatException e) {
  250.                return defaultColor;
  251.             }
  252.          }
  253.          if (nums[0] < 0 || nums[0] > 255 || nums[1] < 0 || nums[1] > 255 || nums[2] < 0 || nums[2] > 255)
  254.             return defaultColor;
  255.          return new Color((int)Math.round(nums[0]), (int)Math.round(nums[1]), (int)Math.round(nums[2]));
  256.       }
  257.    }
  258.    
  259.    private String[] colorNames = { "black", "red", "blue", "green", "yellow",
  260.                                           "cyan", "magenta", "gray", "darkgray",
  261.                                           "lightgray", "pink", "orange", "white" };
  262.    private Color[]  colors = { Color.black, Color.red, Color.blue, Color.green, Color.yellow,
  263.                                       Color.cyan, Color.magenta, Color.gray, Color.darkGray,
  264.                                       Color.lightGray, Color.pink, Color.orange, Color.white };
  265.  
  266. } // end class evaluator
  267.