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. //
  19. import java.util.StringTokenizer;
  20. import edu.hws.jcm.awt.*;
  21. import edu.hws.jcm.functions.*;
  22. //
  23. import java.awt.*;
  24. import java.awt.event.*;
  25. import java.io.*;
  26. import java.net.*;
  27. import java.util.*;
  28. import java.applet.Applet;
  29.  
  30. /**
  31.  * A DataPlotApplet shows a data plot of data from a DataTableInput.
  32.  * The user can enter the data in a two-column table that is shown in
  33.  * the applet.  It is also possible to configure the applet with a menu
  34.  * of file names.  These files, which must be in the same directory as
  35.  * the Web page on which the applet appears, will appear in a menu.
  36.  * A file can contain data for the table, with two numbers per line.
  37.  * When the user loads the file, the data replaces the data in the table.
  38.  */
  39.  
  40. public class DataPlotApplet extends GenericGraphApplet implements ActionListener {
  41.  
  42.    private Frame frame;       // If non-null, a separate window.
  43.    private String frameTitle; // Title for the separate window.
  44.    private Button launchButton;  // If non-null, then clicking this buttons opens a separate window.
  45.    private String launchButtonName;  // Name for the launch button.
  46.    
  47.    private DataTableInput table;    //  The table for input of data.
  48.    private DataPlot dataPlot; //  The data plot of the data.
  49.    private DisplayCanvas canvas;    //  The DisplayCanvas on which the plot is drawn.
  50.    private Button loadFileButton;   //  When clicked, a data file is loaded.
  51.    private Choice fileMenu;         //  Pop-up menu containing names of functions.
  52.    private String[] fileNames;      //  Names of data files associated with menu entries.
  53.    private Controller mainController;  // Controller from the main JCMPanel.
  54.  
  55.    /**
  56.     * The init() method is called by the system to set up the applet.
  57.     * If the applet does not appear as a button, then init() creates the main panel of the applet
  58.     * and calls setUpMainPanel to set it up.
  59.     */
  60.    public void init() {
  61.  
  62.       frameTitle = getParameter("FrameTitle"); // Get title to be used for separate window, if any.
  63.       if (frameTitle == null) {
  64.          frameTitle = "Data Plots";
  65.          int pos = frameTitle.lastIndexOf('.');
  66.          if (pos > -1)
  67.             frameTitle =  frameTitle.substring(pos+1);
  68.       }
  69.       setLayout(new BorderLayout());
  70.       int height = getSize().height;
  71.       launchButtonName = getParameter("LaunchButtonName");
  72.       if ( (height > 0 && height <= 50) || launchButtonName != null) {
  73.               // Use a separater window and only show a button in the applet.
  74.           if (launchButtonName == null)
  75.                launchButtonName = "Launch " + frameTitle;
  76.           launchButton = new Button(launchButtonName);
  77.           add(launchButton, BorderLayout.CENTER);
  78.           launchButton.addActionListener(this);
  79.       }
  80.       else {
  81.              // Show the main panel in the applet, not in a separate window.
  82.           add(makeMainPanel(), BorderLayout.CENTER);
  83.       }
  84.    }
  85.  
  86.    /*
  87.     * Create the main panel of the applet.
  88.     */
  89.    public Panel makeMainPanel() {
  90.    
  91.       // Make the main panel
  92.  
  93.       JCMPanel panel = new JCMPanel(2);
  94.       mainController = panel.getController();
  95.       panel.setBackground(new Color(0,0,180));
  96.       panel.setInsetGap(2);
  97.       setLayout(new BorderLayout());
  98.      
  99.       // Make a DataInputTable with two columns
  100.      
  101.       table = new DataTableInput(null, 2);
  102.       table.setColumnName(0, getParameter("ColumnName1", "X"));
  103.       table.setColumnName(1, getParameter("ColumnName2", "Y"));
  104.       table.setThrowErrors(true);
  105.       if ( "yes".equalsIgnoreCase(getParameter("ShowColumnTitles","yes")))
  106.          table.setShowColumnTitles(true);
  107.       if ( "yes".equalsIgnoreCase(getParameter("ShowRowNumbers","yes")))
  108.          table.setShowRowNumbers(true);
  109.                                  
  110.       // Make input boxes for getting expressions that can include
  111.       // the variables associated with the table.  Initially, the
  112.       // expressions are just the column names.
  113.  
  114.       Parser parser = new Parser();
  115.       table.addVariablesToParser(parser);
  116.       ExpressionInput input1 = new ExpressionInput(table.getColumnName(0),parser);
  117.       input1.setOnUserAction(mainController);
  118.       ExpressionInput input2 = new ExpressionInput(table.getColumnName(1),parser);
  119.       input2.setOnUserAction(mainController);
  120.      
  121.       // Make a data plot that graphs the first expressiong vs. the second expression.
  122.  
  123.       dataPlot = new DataPlot(table, input1.getExpression(), input2.getExpression());
  124.       if ( ! "yes".equalsIgnoreCase(getParameter("ShowRegressionLine","yes")))
  125.         dataPlot.setShowRegressionLine(false);
  126.       if ( ! "yes".equalsIgnoreCase(getParameter("MissingValueIsError","yes")))
  127.         dataPlot.setMissingValueIsError(false);
  128.        
  129.       // Create the display canvas where the scater plot will be shown.
  130.  
  131.  
  132.       canvas = new DisplayCanvas();
  133.       Axes axes = new Axes();
  134.       canvas.add(axes);
  135.      // canvas.add(new Axes());
  136.       canvas.add(dataPlot);
  137.       mainController.setErrorReporter(canvas);
  138.     //evers
  139.  
  140.       if ( ! "no".equalsIgnoreCase(getParameter("UseGrid", "no")) ) {
  141.          Grid g = new Grid();
  142.         canvas.add(g);
  143.       }
  144.       // A compute button to recompute everything.
  145.      
  146.       ComputeButton computeButton = new ComputeButton("Vernieuwen");
  147.       computeButton.setOnUserAction(mainController);
  148.       computeButton.setBackground(Color.lightGray);
  149.      
  150.       // A menu of files that can be loaded.  If no filenames are provided as
  151.       // applet parameters, then menu is null.
  152.      
  153.       Panel menu = makefileMenu();
  154.      
  155.       // Lay out the components in the applet.
  156.      
  157.       JCMPanel inputPanel = null;
  158.       Panel bottom = null;  //might not be a JCMPanel
  159.       if ( "yes".equalsIgnoreCase(getParameter("UseExpressionInputs","yes"))) {
  160.          inputPanel = new JCMPanel(1,2);
  161.          inputPanel.setBackground(Color.lightGray);
  162.          JCMPanel leftInput = new JCMPanel();
  163.          leftInput.add(new Label("  Plot:  "), BorderLayout.WEST);
  164.          leftInput.add(input1, BorderLayout.CENTER);
  165.          inputPanel.add(leftInput);
  166.          JCMPanel rightInput = new JCMPanel();
  167.          rightInput.add(new Label(" versus: "), BorderLayout.WEST);
  168.          rightInput.add(input2, BorderLayout.CENTER);
  169.          inputPanel.add(rightInput);
  170.          bottom = new JCMPanel(new BorderLayout(12,3));
  171.          bottom.add(inputPanel, BorderLayout.CENTER);
  172.          bottom.add(computeButton, BorderLayout.EAST);
  173.       }
  174.      
  175.       if ( dataPlot.getShowRegressionLine() && "yes".equalsIgnoreCase(getParameter("ShowStats","yes")) ) {
  176.             // Make a display label to show some statistics about the data.
  177.          DisplayLabel dl = new DisplayLabel(
  178.                "Helling = #;  Intercept = #;  Correlatie = #",
  179.                 new Value[] { dataPlot.getValueObject(DataPlot.SLOPE),
  180.                               dataPlot.getValueObject(DataPlot.INTERCEPT),
  181.                               dataPlot.getValueObject(DataPlot.CORRELATION) }
  182.             );
  183.          dl.setAlignment(Label.CENTER);
  184.          dl.setBackground(Color.lightGray);
  185.          dl.setForeground(new Color(200,0,0));
  186.          dl.setFont(new Font("Serif",Font.PLAIN,14));
  187.          if (bottom != null)
  188.             bottom.add(dl, BorderLayout.SOUTH);
  189.          else {
  190.             bottom = new JCMPanel(new BorderLayout(12,3));
  191.             bottom.add(dl, BorderLayout.CENTER);
  192.             bottom.add(computeButton, BorderLayout.EAST);
  193.          }
  194.       }
  195.      
  196.       if (bottom == null) {
  197.          if (menu != null)
  198.             menu.add(computeButton, BorderLayout.EAST);
  199.          else {
  200.             bottom = new Panel();
  201.             bottom.add(computeButton);
  202.          }
  203.       }
  204.      
  205.       panel.add(canvas, BorderLayout.CENTER);
  206.       panel.add(table, BorderLayout.WEST);
  207.       if (bottom != null)
  208.          panel.add(bottom, BorderLayout.SOUTH);
  209.       if (menu != null)
  210.          panel.add(menu, BorderLayout.NORTH);
  211.       else {
  212.          String title = getParameter("PanelTitle");
  213.          if (title != null) {
  214.             Label pt = new Label(title, Label.CENTER);
  215.             pt.setBackground(Color.lightGray);
  216.             pt.setForeground(new Color(200,0,0));
  217.             pt.setFont(new Font("Serif",Font.PLAIN,14));
  218.             panel.add(pt, BorderLayout.NORTH);
  219.          }
  220.       }
  221.          
  222.       return panel;
  223.      
  224.    } // end makeMainPanel()
  225.    
  226.    
  227.    private Panel makefileMenu() {
  228.          // If the applet tag contains params named "File", "File1", "File2", ..., use
  229.          // their values to make a file menu.  If the value of the param contains a ";",
  230.          // then the first part, up to the ";", goes into the menu and the second part
  231.          // is the name of the file.  If there is no ";", then the entire value is
  232.          // shown in the menu and is also used as the name of the file.  The actual
  233.          // files must be in the same directory as the Web page that contains the applet.
  234.       Vector names = new Vector();
  235.       fileMenu = new Choice();
  236.       String file = getParameter("File");
  237.       int ct = 1;
  238.       if (file == null) {
  239.          file = getParameter("File1");
  240.          ct = 2;
  241.       }
  242.       while (file != null) {
  243.          file = file.trim();
  244.          int pos = file.indexOf(";");
  245.          String menuEntry;
  246.          if (pos == -1)
  247.             menuEntry = file;
  248.          else {
  249.             menuEntry = file.substring(0,pos).trim();
  250.             file = file.substring(pos+1).trim();
  251.          }
  252.          names.addElement(file);
  253.          fileMenu.add(menuEntry);
  254.          file = getParameter("File" + ct);
  255.          ct++;
  256.       }
  257.       if (names.size() == 0) {
  258.          fileMenu = null;
  259.          return null;
  260.       }
  261.       else {
  262.          fileNames  = new String[names.size()];
  263.          for (int i = 0; i < names.size(); i++)
  264.             fileNames[i] = (String)names.elementAt(i);
  265.          Panel p = new Panel();
  266.          p.setBackground(Color.lightGray);
  267.          p.setLayout(new BorderLayout(5,5));
  268.          p.add(fileMenu,BorderLayout.CENTER);
  269.          loadFileButton = new Button("datafile: ");
  270.          loadFileButton.addActionListener(this);
  271.          p.add(loadFileButton,BorderLayout.WEST);
  272.          fileMenu.setBackground(Color.white);
  273.          return p;
  274.       }
  275.    }
  276.    
  277.    private void doLoadFile(String name) {
  278.         // Load the file from the same directory as the Web page and put the data
  279.         // from the file into the table.  The file should contain two numbers on
  280.         // each line.
  281.       InputStream in;
  282.       try {
  283.          URL url = new URL(getDocumentBase(), name);
  284.          in = url.openStream();
  285.       }
  286.       catch (Exception e) {
  287.          canvas.setErrorMessage(null,"Unable to open file named \"" + name + "\": " + e);
  288.          return;
  289.       }
  290.       Reader inputReader = new InputStreamReader(in);
  291.       try {
  292.          table.readFromStream(inputReader);
  293.          inputReader.close();
  294.       }
  295.       catch (Exception e) {
  296.          canvas.setErrorMessage(null,"Unable to get data from file \"" + name + "\": " + e.getMessage());
  297.          return;
  298.       }
  299.       mainController.compute();
  300.    }
  301.  
  302.    /**
  303.     *  Respond when user clicks a button; not meant to be called directly.
  304.     *  This opens and closes the separate window.
  305.     */
  306.    synchronized public void actionPerformed(ActionEvent evt) {
  307.       Object source = evt.getSource();
  308.       if (loadFileButton != null && source == loadFileButton) {
  309.          doLoadFile( fileNames[fileMenu.getSelectedIndex()] );
  310.       }
  311.       else if (source == launchButton && launchButton != null) {
  312.             // Open or close separate frame.
  313.          launchButton.setEnabled(false);
  314.          if (frame == null) {
  315.             frame = new Frame(frameTitle);
  316.             frame.add(makeMainPanel());
  317.             frame.addWindowListener( new WindowAdapter() {
  318.                   public void windowClosing(WindowEvent evt) {
  319.                      frame.dispose();
  320.                   }
  321.                   public void windowClosed(WindowEvent evt) {
  322.                      frameClosed();
  323.                   }
  324.                } );
  325.             frame.pack();
  326.             frame.setLocation(50,50);
  327.             frame.setVisible(true);
  328.             launchButton.setLabel("Sluit Venster");
  329.             launchButton.setEnabled(true);
  330.          }
  331.          else {
  332.             frame.dispose();
  333.          }
  334.       }
  335.    }
  336.    
  337.    synchronized private void frameClosed() {
  338.         // respond when separate window closes.
  339.       frame = null;
  340.       launchButton.setLabel(launchButtonName);
  341.       launchButton.setEnabled(true);
  342.    }
  343.    
  344.    /**
  345.     *  Return the applet parameter with a given param name, but if no
  346.     *  such applet param exists, return a default value instead.
  347.     */
  348.    protected String getParameter(String paramName, String defaultValue) {
  349.        String val = getParameter(paramName);
  350.        return (val == null)? defaultValue : val;
  351.    }
  352.    
  353. } // end class DataPlotApplet
  354.