| The following two applications illustrate how an experiment simulation 
              creates data and saves it to a files, which are then read by an 
              analysis program. We split the mass drop simulation program discussed 
              in Chapter 9: Physics: 
              Experimental Simulation with Analysis Module into two programs: 
             
              DropGenerator - generates 
                the drop events and writes the detector simulated data to a file.DropDataAnalysis 
                 - reads the data from the files created by DropGenerator 
                and fits a curve to the Y vs T curve.  Ideally, DropDataAnalysis 
               would read files in the exact same format but generated 
              from the actual experiment detector. This would insure that the 
              analysis was applied consistently. Also, it allows one to compare 
              the simulated data to the real data and see if there are aspects 
              that are not understoode. (E.g. in the next 
              chapter we will look at systematic error analysis..)   
              
                 
                  | DropGenerator
 
  |   
                  |  
                      DropGenerator 
                        - 
                        Using code from the Chapter 
                        9: Physics: Experiment Simulation with Analysis Module, 
                        which simulates a strip chart type of drop experiment, 
                        this program sends data for each drop to a file. This 
                        file will be analyzed by DropDataAnalysis shown below. 
                          + Previous 
                        Classes:Chapter 
                        9: Physics: DropPanelDetect, 
                        DropModelDetect
 Chapter 
                        9: Physics:  
                        DropDetector2, 
                        Detector
 Chapter 
                        6: Tech: PlotPanel.java, 
                        PlotFormat.java
 
 |   
                  | Java techniques of interest: 
                      Enumerated types used to direct the data output controlsUsing DataOutputStream to 
                        write out data of different primitive types.  |   
                  | import 
                    javax.swing.*; import java.awt.*;
 import java.awt.event.*;
 import java.io.*;
 
 /**
 * This program simulates an experiment in which 
                    measurements
 * are made during the fall of a mass in a constant 
                    gravitational
 * field. The measurements will be used in a separate 
                    analysis program
 * to determine the acceleration constant.
 *
 * The applet uses DropPanelDetect to display the 
                    experimental setup
 * and the falling mass. The DropDetector object 
                    draws the detector
 * on this panel.
 *
 * The java.util.Timer and java.util.TimerTask 
                    are used
 * to update the animation of the drop.
 *
 * Includes "Drop" button to initiate the dropping.
 * The number of drops and a speed factor taken 
                    from 2 text fields.
 * "Reset"  button clears the histogram.
 * In standalone mode, the Exit button closes the 
                    program.
 *
 * Data for each drop is optionally written to 
                    a binary file by
 * setting a checkbox. The data will be written 
                    to a file
 * using the name given in the a field.
 *
 * This program will run as an applet inside an 
                    application frame.
 * (Data output will not work in applet mode in 
                    browser.)
 *
 **/
 public class DropGenerator extends JApplet
 implements ActionListener, ItemListener
 {
 // The DropPanel displays the animation of the 
                    falling mass.
 DropPanelDetect fDropPanel;
 
 // The DropModel generates the physics data.
 DropModelDetect fDropModel;
 
 // Use a detector to measure the drop times.
 Detector fDetector;
 
 // File handling for the output ntuple data
 File fOutFile;
 String fOutFileName = "dropData.dat";
 DataOutputStream fDataOut;
 boolean fOutToFile = false;
 JCheckBox fFileCheckBox;
 JTextField fFileTextField;
 
 // Enumerated type used to direct output operations
 public enum OutputCmd {OUT_SETUP, OUT_WRITE, OUT_CLOSE}
 
 // Array to hold data for each drop
 double fData[][];
 
 // Use the java.util Timer and TimerTask combo
 // for timing events.
 java.util.Timer fTimer;
 
 // A text field for getting the number of drops 
                    for a
 // run and the position smearing std.dev. in cm.
 JTextField fMaxNumDropsField;
 JTextField fPosSigmaFactorField;
 
 // Flag for whether the applet is in a browser
 // or running via the main () below.
 boolean fInBrowser = true;
 
 //Buttons
 JButton fGoButton;   // start drop
 JButton fClearButton;// resets histogram
 JButton fExitButton;
 
 // Starting coordinates of drop
 double fXBallStart =  25.0; // cm
 double fYBallStart = 200.0; // cm
 double fYBallEnd   =   0.0; 
                    // cm
 
 // Range of the drop time.
 double fTStart = 0.00; // sec
 double fTEnd   = 0.75; // sec
 
 // SD in the measured values for the marker positions 
                    and t (sec).
 //  (Allow for smearing of marker position 
                    for further experimentation.)
 double [] fMeasurementSigmas = {2.0, 0.0};
 
 // Integer and double arrays to pass info to the 
                    detector
 int []    fDetectorSetup;
 double [] fDetectorParameters;
 
 // Coordinate of ball.
 double fXBall;
 double fYBall;
 
 // Initial velocity.
 double fVyBallStart = 0.0;
 double fVxBallStart = 0.0;
 
 // Time in millisecs for the drop
 double fTDropTotal;
 double fTFrame = 0.020; // in secs
 
 // Speed up or slow down factor for animation:
 double fTFactor = 1.0;
 
 // Allow for multiple drops per "run"
 int fMaxNumDrops = 10;
 int fNumDrops = 0;
 
 // Number of times to measure the position during 
                    the drop.
 int fMaxNumMeasurements = 40;
 // Number of measurements actually taken for a 
                    given event.
 int fNumMeasures;
 
 /**
 *  Initialize the display. 
                    Create Detector and Model
 *  objects to use for the 
                    physics and experiment simulation.
 *  DropPanelDetect displays 
                    the dropping ball and the
 *  detector.
 **/
 public void init () {
 
 // Create a detector
 fDetector = new DropDetector2 ();
 
 // Need arrays to pass setup info 
                    to the detector.
 fDetectorSetup = new int[1];
 fDetectorSetup[0] = fMaxNumMeasurements;
 
 // Do a measurement for every frame
 fDetectorParameters = new double[1];
 fDetectorParameters[0] = fTFrame;
 
 // Pass the detector the necesary 
                    setup info
 fDetector.init (fDetectorSetup, fDetectorParameters, 
                    fMeasurementSigmas);
 
 // Create the drop physics model
 fDropModel = new DropModelDetect (fDetector);
 fDropModel.reset (fYBallStart, fVyBallStart);
 
 JPanel panel = new JPanel (new BorderLayout 
                    ());
 
 // Use a textfield to get the number 
                    of drops per run.
 fMaxNumDropsField =
 new JTextField (Integer.toString 
                    (fMaxNumDrops), 10);
 
 // Use a textfield to get smearing  (std.dev. 
                    in cm) of the position.
 fPosSigmaFactorField =
 new JTextField (Double.toString 
                    (fMeasurementSigmas[0]), 10);
 
 // If return hit after entering text, 
                    the actionPerformed will be invoked.
 fMaxNumDropsField.addActionListener 
                    (this);
 fPosSigmaFactorField.addActionListener 
                    (this);
 
 fGoButton = new JButton ("Drop");
 fGoButton.addActionListener (this);
 
 // Here the clear button will reset 
                    the plots
 fClearButton = new JButton ("Reset");
 fClearButton.addActionListener (this);
 
 fExitButton = new JButton ("Exit");
 fExitButton.addActionListener (this);
 
 JPanel control_panel = new JPanel 
                    (new GridLayout (1,2));
 JPanel panel1 = new JPanel (new GridLayout 
                    (1,2));
 JPanel panel2 = new JPanel (new GridLayout 
                    (1,3));
 
 panel1.add (fMaxNumDropsField);
 panel1.add (fPosSigmaFactorField);
 
 panel2.add (fGoButton);
 panel2.add (fClearButton);
 panel2.add (fExitButton);
 
 control_panel.add (panel1);
 control_panel.add (panel2);
 
 // Set up the output file
 JPanel file_panel = new JPanel ();
 fFileCheckBox = new JCheckBox ("Output 
                    to File?");
 
 // Put the text on the left side of 
                    the box.
 fFileCheckBox.setHorizontalTextPosition(SwingConstants.LEFT);
 fFileCheckBox.addItemListener (this);
 fFileTextField= new JTextField (fOutFileName,15);
 file_panel.add (fFileCheckBox);
 
 // Jusify the text on the right side 
                    of the label
 file_panel.add (new JLabel ("   
                    File name:", SwingConstants.RIGHT));
 file_panel.add (fFileTextField);
 
 // Create a holder for both the program  and 
                    the file controls
 JPanel controls_panel = new JPanel(new 
                    GridLayout (2,1));
 
 controls_panel.add (control_panel);
 controls_panel.add (file_panel);
 
 // Create an instance of the DropPanel
 // Make the panel 10% taller than 
                    starting position.
 fDropPanel = new DropPanelDetect (fYBallStart*1.1, 
                    0.0, fDetector);
 
 JPanel holder_panel = new JPanel (new 
                    BorderLayout ());
 holder_panel.add (fDropPanel,"Center");
 
 panel.add (holder_panel,"Center");
 panel.add (controls_panel,"South");
 
 // Add text area with scrolling to 
                    the content pane.
 add (panel);
 
 } // init
 
 /** Stop the timer if the browser page unloaded. 
                    */
 public void stop () {
 runDone ();
 } // stop
 
 /**
 *  Respond to the buttons. 
                    For a click on "Drop" button,
 *  execute the number of 
                    drops in the text field.
 *  Also, obtain the smearing 
                    factor for the y measurements
 *  from the other text field. 
                    The Reset button will clear the
 *  plots and reset the drop 
                    stats.
 **/
 public void actionPerformed (ActionEvent e) {
 Object source = e.getSource ();
 if (source == fGoButton) {
 if (fGoButton.getText 
                    ().equals ("Drop")) {
 try {
 fMaxNumDrops 
                    =
 Integer.parseInt 
                    (fMaxNumDropsField.getText ());
 
 // 
                    Get new sigma for position smearing
 fMeasurementSigmas[0] 
                    =
 Double.parseDouble 
                    (fPosSigmaFactorField.getText ());
 
 // 
                    Update the position smearing
 fDetector.init 
                    (fDetectorSetup, fDetectorParameters,
 fMeasurementSigmas);
 }
 catch (NumberFormatException 
                    ex) {
 // 
                    Could open an error dialog here but just
 // 
                    display a message on the browser status line.
 if 
                    ( fInBrowser)
 showStatus 
                    ("Bad input value");
 else
 System.out.println 
                    ("Bad input value");
 return;
 }
 dropReset 
                    ();
 fGoButton.setText 
                    ("Stop");
 fClearButton.setEnabled 
                    (false);
 
 } else {
 // 
                    Stop without finishing the current drop.
 runDone 
                    ();
 }
 } else if (source == fClearButton) 
                    {
 repaint ();
 } else if (!fInBrowser)
 System.exit 
                    (0);
 } // actionPerformed
 
 
 /**
 * Respond to the file checkbox. If 
                    box checked,
 * then open the file for output. Use 
                    file name
 * given in the text field on the interface.
 **/
 public void itemStateChanged (ItemEvent evt) {
 if (evt.getStateChange () == ItemEvent.SELECTED) 
                    {
 fOutToFile = true;
 } else {
 fOutToFile = false;
 }
 } // itemStateChanged
 
 
 /**
 * Use the inner class technique to 
                    define the
 * TimerTask subclass for stepping 
                    through the
 * drop calculation and the frame refresh.
 *
 * Use the real time in the drop calculation 
                    instead
 * of the given frame rate times in 
                    case there were
 * delays from thread interruptions, 
                    the processing
 * in the parts of the program take 
                    extra time, etc.
 **/
 class PaintHistTask extends java.util.TimerTask 
                    {
 public void run () {
 
 // Drop the ball
 fYBall = fDropModel.step 
                    (fTFactor * fTFrame);
 
 // Update the position 
                    of the ball in the
 // animation and redraw 
                    the frame.
 fDropPanel.updatePosition 
                    (fXBall, fYBall);
 
 // Check if ball has crossed 
                    the finish line.
 if (fYBall <= fYBallEnd) 
                    dropDone ();
 } // run
 } // PaintHistTask
 
 
 /**
 *  This method handles the 
                    output to the file.
 *  The ennumerated type 
                    OutputCmd indicates which
 *  operation: setup, writing 
                    each drop data set, and
 *  stream closeing should 
                    be executed.
 **/
 void outputToFile (OutputCmd output_cmd) {
 
 switch (output_cmd) {
 // Setup creats the File 
                    object and opens a stream to
 // the file.
 case OUT_SETUP:
 // Get file 
                    name from the text field
 fOutFileName 
                    = fFileTextField.getText ();
 // And created 
                    a File object for it
 fOutFile = 
                    new File (fOutFileName);
 
 try {
 // 
                    Open an output stream to the file.
 FileOutputStream 
                    file_output = new FileOutputStream (fOutFile);
 // 
                    Wrap the FileOutputStream with a DataOutputStream
 fDataOut 
                    = new DataOutputStream (file_output);
 
 // 
                    Create a header for the data file.
 // 
                    Post the current time.
 fDataOut.writeLong 
                    (System.currentTimeMillis());
 // 
                    The file will have no more than these number of drops
 // 
                    (could be less if run stopped early by the user)
 fDataOut.writeInt 
                    (fMaxNumDrops);
 // 
                    Add the maximum number of measurements per drop
 fDataOut.writeInt 
                    (fMaxNumMeasurements);
 }
 catch (FileNotFoundException 
                    fnfe) {
 System.out.println 
                    ("File Not Found = " + fnfe);
 }
 catch (IOException 
                    ioe) {
 System.out.println 
                    ("IO exception = " + ioe );
 }
 break;
 
 case OUT_WRITE:
 // Now write 
                    the data for this event.
 try {
 fDataOut.writeInt 
                    (fNumDrops); // drop number
 fDataOut.writeInt 
                    (fNumMeasures); // Number of measurements
 // 
                    Write the data as an position/time pair
 for 
                    (int i=0; i < fNumMeasures; i++) {
 fDataOut.writeDouble 
                    (fData[0][i]); // positions
 fDataOut.writeDouble 
                    (fData[1][i]); // times
 }
 }
 catch (IOException 
                    e) {
 System.out.println 
                    ("IO exception = " + e );
 }
 break;
 
 case OUT_CLOSE:
 // Close file 
                    when finished with it..
 try {
 fDataOut.close 
                    ();
 }
 catch (IOException 
                    e) {
 System.out.println 
                    ("IO exception = " + e );
 }
 break;
 }
 
 } // outputToFile
 
 
 /**
 *  Do the setup and then 
                    start the drops.
 *  Before each set of drops, 
                    need to create a new timer,
 *  and set up its schedule. 
                    The PaintHistTask innner class
 *  object will do the setup 
                    for each frame of a drop animation.
 **/
 void dropReset () {
 // Before starting the drop, create 
                    the timer task
 // that will cause the histogram display 
                    to update
 // during the filling.
 // Create a timer. TimerTask created 
                    in MakeHist ()
 fTimer = new java.util.Timer ();
 
 fDropModel.reset (fYBallStart, fVyBallStart);
 fDropPanel.reset (fXBallStart, fYBallStart);
 
 // Reset time sum
 fTDropTotal = 0.0;
 fNumDrops = 0;
 fYBall = fYBallStart;
 fXBall = fXBallStart;
 
 // Reset the detector.
 fDetector.reset ();
 
 repaint ();
 
 if (fOutToFile) outputToFile (OutputCmd.OUT_SETUP);
 
 // Start the run by starting the timer 
                    after 20ms and then
 // repeat callsto run in PaintHistTask 
                    object by the rate
 // set by the fTFrame value.
 fTimer.schedule (new PaintHistTask 
                    (), 20, (int) (fTFrame*1000));
 
 } // dropReset
 
 /**
 *  Invoked after a drop 
                    ends bottom. Reset
 *  all the parameters to 
                    set up for another drop.
 **/
 public void dropDone () {
 // Get the data  (times 
                    and positions during the drop)
 // from the detector and analyze it
 fData = fDetector.getResults ();
 fNumMeasures = fDetector.getNumMeasurements 
                    ();
 ++fNumDrops;
 if (fOutToFile) outputToFile (OutputCmd.OUT_WRITE);
 
 // Check if all drops completed.
 if (fNumDrops == fMaxNumDrops){
 // If so then finish up 
                    the data recording
 // for this run and return.
 runDone ();
 return;
 }
 
 // Reset time sum
 fTDropTotal = 0.0;
 fYBall = fYBallStart;
 fXBall = fXBallStart;
 
 fDropPanel.reset (fXBallStart, fYBallStart);
 fDropModel.reset (fYBallStart, fVyBallStart);
 fDetector.reset ();
 
 } // dropDone
 
 
 /**
 *  Invoked when all the 
                    drops in a run  (set of drops) are done.
 *  Kills the timer to stop 
                    the animation.  (A new timer will be
 *  created in the dropReset 
                    () for the next run.)
 **/
 public void runDone () {
 
 // Stop the animation.
 fTimer.cancel ();
 
 // Reset the buttons.
 fGoButton.setText ("Drop");
 fClearButton.setEnabled (true);
 
 if (fOutToFile) outputToFile (OutputCmd.OUT_CLOSE);
 
 } // runDone
 
 /** Offer the option of running the applet in 
                    an app frame. */
 public static void main (String[] args) {
 //
 int frame_width=450;
 int frame_height=300;
 
 //
 DropGenerator applet = new DropGenerator 
                    ();
 applet.fInBrowser = false;
 applet.init ();
 
 // Following anonymous class used 
                    to close window & exit program
 JFrame f = new JFrame ("Drop Test");
 f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
 
 // Add applet to the frame
 f.getContentPane ().add ( applet);
 f.setSize (new Dimension (frame_width,frame_height));
 f.setVisible (true);
 } // main
 
 } // DropGenerator
 |      The following program analyzes the data in the files written by 
              DropGenerator shown above. 
              
              
                 
                  | DropDataAnalysis 
  |   
                  |  
                      DropDataAnalysis 
                        - 
                        read in data generated by DropGenerator and analyze it 
                        with the DropAnalyzer class. Class offers menu bar with 
                        drop down File menu to select the data file. The file 
                        name is displayed in the JTextField.   + Previous 
                        Classes:Ch. 
                        9: Physics: DropAnalyzer
 Ch. 
                        8: Physics: 
                        Fit.java, 
                        FitPoly.java, 
                        DrawPoly.java
 Ch. 
                        6: Tech:  
                        DrawPanel.java, 
                        DrawPoints.java, 
                        DrawFunction.java
 Ch. 
                        6: Tech: PlotPanel, 
                        PlotFormat
 
 |   
                  | Java techniques of interest: 
                      Enumerated types used to direct the data input controls 
                        and status of the input.Long time (in msecs) conversion to date and time.Using DataInputStream to obtain 
                        data of different primitive types. Using the JFileChooser to 
                        select the data file.Modularity is illustrated by using the DropAnalyzer 
                        class from Chapter 9 without any modifications. |   
                  | import 
                    javax.swing.*; import java.awt.*;
 import java.awt.event.*;
 import java.io.*;
 import java.util.*;
 import java.text.*;
 
 /**
 * This program reads in data from a file created 
                    by DropGenerator.
 * For each drop event the data is sent to an instance 
                    of DropAnalyzer.
 * When all the data is read, a fit is made to 
                    the average y vs t curve
 * to determine the g parameter as before.
 **/
 public class DropDataAnalysis extends JFrame
 implements 
                    ActionListener
 {
 // UI control variables
 JMenuItem fMenuOpen;
 JMenuItem fMenuSave;
 JMenuItem fMenuClose;
 
 JTextField  fFileTextField;
 DropAnalyzer fDropAnalyzer;
 
 JButton fGoButton;
 JButton fButton2;
 
 // Change these names as needed
 String fButtonName1 = "Go";
 String fButtonName2 = "Option";
 
 // Filter and File object for fFile chooser
 DataFilter fDataFilter = new DataFilter ();
 File fInFile;
 String fInFileName = "[select input file]";
 // DataInputStream is used to read the data.
 DataInputStream fInData;
 
 // 2-D array to hold position and time data for
 // each drop.
 double [][] fData;
 
 // The data file includes the time for when it
 // was made.
 Date dateOfData;
 
 // Enumerated type used to direct output operations
 public enum InputCmd {IN_SETUP, IN_READ, OUT_CLOSE}
 
 // Enumerated type used to direct output operations
 public enum InputStatus {OK, EVENT_READ, EOF, 
                    ERROR}
 InputStatus fInputStatus;
 
 // Maximum number of measurements along each drop 
                    trajectory
 int fMaxNumMeasurements;
 // Number of measurements on current drop
 int fNumMeasures;
 // Drop number in the file
 int fNumDrops;
 // Max number of drops in the file
 int fMaxNumDrops;
 
 // The following experimental settings could be 
                    allowed
 // to vary and then recorded in the data header 
                    for a given
 // run. However, this program assumes they are 
                    constant.
 
 // Starting coordinates of drop
 double fXBallStart =  25.0; // cm
 double fYBallStart = 200.0; // cm
 double fYBallEnd   =   0.0; 
                    // cm
 
 // Range of the drop time.
 double fTStart = 0.00; // sec
 double fTEnd   = 0.75; // sec
 
 /** Create a frame for displaying the GUI.**/
 public static void main (String [] args) {
 String title="Drop Data Analysis";
 DropDataAnalysis f = new DropDataAnalysis 
                    (title);
 f.setVisible (true);
 } // main
 
 /**
 * The GUI is built in the constructore. 
                    Pass a title
 * to the frame via the constructor  argument.
 **/
 DropDataAnalysis (String title) {
 super (title);
 
 // Create a user interface.
 setLayout (new BorderLayout ());
 
 // Create an analyzer and add its 
                    panel to the frame.
 fDropAnalyzer = new DropAnalyzer (fYBallEnd, 
                    fYBallStart,
 fTStart, 
                    fTEnd);
 add (fDropAnalyzer.getPanel (), "Center");
 
 // Create a panel with a textfield 
                    and two buttons
 fFileTextField = new JTextField (fInFileName);
 
 fGoButton = new JButton (fButtonName1);
 fGoButton.addActionListener (this);
 
 // Create a second button to provide 
                    option of
 // later providing a second operation 
                    on the data.
 fButton2 = new JButton (fButtonName2);
 // But make inactive for this version 
                    of the
 // drop data analysis.
 fButton2.setEnabled (false);
 
 JPanel panel = new JPanel (new GridLayout 
                    (1,2));
 JPanel button_panel = new JPanel (new 
                    GridLayout (1,2));
 panel.add (fFileTextField);
 button_panel.add (fGoButton);
 button_panel.add (fButton2);
 panel.add (button_panel);
 
 add (panel, "South");
 
 // Use the helper method makeMenuItem
 // for making the menu items and registering
 // their listener.
 JMenu m = new JMenu ("File");
 
 // the particular program.
 m.add (fMenuOpen  = makeMenuItem 
                    ("Open"));
 m.add (fMenuClose = makeMenuItem ("Quit"));
 
 JMenuBar mb = new JMenuBar ();
 mb.add (m);
 
 setJMenuBar (mb);
 setSize (400,400);
 setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE);
 
 } // ctor
 
 /**
 * Process events from the frame menu 
                    and the chooser.
 **/
 public void actionPerformed ( ActionEvent e ) 
                    {
 boolean status = false;
 
 String command = e.getActionCommand 
                    ();
 
 if (command.equals (fButtonName1)) 
                    {
 if (fInputStatus == InputStatus.OK) 
                    analyzeData ();
 else
 JOptionPane.showMessageDialog 
                    (
 null,
 "File 
                    not ready", "File Read Error",
 JOptionPane.ERROR_MESSAGE);
 }
 else if (command.equals (fButtonName2)) 
                    {
 
 // Do fButton2 action 
                    here
 
 }
 else if (command.equals ("Open")) 
                    {
 // Open a fFile
 status = openFile ();
 if (!status) {
 JOptionPane.showMessageDialog 
                    (
 null,
 "Error 
                    opening fFile!", "File Open Error",
 JOptionPane.ERROR_MESSAGE);
 fInputStatus 
                    = InputStatus.ERROR;
 } else {
 fInputStatus 
                    = InputStatus.OK;
 }
 
 } else if (command.equals ("Quit")) 
                    {
 dispose ();
 }
 } // actionPerformed
 
 /**
 * This "helper method" makes a menu 
                    item and then
 * registers this object as a listener 
                    to it.
 **/
 private JMenuItem makeMenuItem (String name) {
 JMenuItem m = new JMenuItem ( name 
                    );
 m.addActionListener ( this );
 return m;
 }
 
 /** Carry out the analysis of the data in the 
                    chosen file. **/
 void analyzeData () {
 int evt = 0;
 while (true) {
 // Read an event
 inputFromFile (InputCmd.IN_READ);
 // and analyze it.
 if (fInputStatus == InputStatus.EVENT_READ) 
                    {
 fDropAnalyzer.analyzeDrop 
                    (fData[0], fData[1], fNumMeasures);
 } else
 if (fInputStatus == InputStatus.EOF) 
                    {
 // Analyze 
                    the full run data now.
 fDropAnalyzer.analyzeRun 
                    ();
 break;
 } else
 if (fInputStatus == InputStatus.ERROR) 
                    {
 JOptionPane.showMessageDialog 
                    (
 null,
 "Read 
                    failure", "File Read Error",
 JOptionPane.ERROR_MESSAGE);
 break;
 }
 }
 
 } // analyzeData
 
 /**
 *  This method handles the 
                    input from the data file.
 *  The ennumerated type 
                    InputCmd indicates which
 *  operation: setup, writing 
                    each drop data set, and
 *  stream closeing should 
                    be executed.
 **/
 void inputFromFile (InputCmd input_cmd) {
 
 switch (input_cmd) {
 
 case IN_SETUP:
 try {
 // 
                    Wrap the FileInputStream with a DataInputStream
 FileInputStream 
                    file_input = new FileInputStream (fInFile);
 fInData 
                    = new DataInputStream (file_input );
 
 // 
                    Read header
 
 // 
                    First get the time of the run (in millisecs since 1970)
 long 
                    data_time = fInData.readLong ();
 // 
                    And convert to a date object.
 dateOfData 
                    = new Date (data_time);
 // 
                    Then convert this date to a string with date and time
 DateFormat 
                    df =
 DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT);
 String 
                    run_date = df.format(dateOfData);
 fDropAnalyzer.fDrawPanel.setTitle 
                    ("Data for " + run_date);
 
 // 
                    Now get the other data in the header
 fMaxNumDrops 
                    = fInData.readInt ();
 fMaxNumMeasurements 
                    = fInData.readInt ();
 
 // 
                    Tell the analyzer how the max number of drop events to
 // 
                    expect and the max number of measurements for a drop.
 fDropAnalyzer.initRun 
                    (fMaxNumDrops, fMaxNumMeasurements);
 
 // 
                    Need an array to hold data for a single drop
 fData 
                    = new double[2][fMaxNumMeasurements];
 }
 catch (FileNotFoundException 
                    fnfe) {
 JOptionPane.showMessageDialog 
                    (
 null,
 "Cannot 
                    open file!", "File Open Failure",
 JOptionPane.ERROR_MESSAGE);
 fInputStatus 
                    = InputStatus.ERROR;
 }
 catch (IOException 
                    ioe) {
 JOptionPane.showMessageDialog 
                    (
 null,
 "I/O 
                    failure", "File Read Error",
 JOptionPane.ERROR_MESSAGE);
 fInputStatus = InputStatus.ERROR;
 }
 break;
 
 case IN_READ:
 // Now read 
                    the data and analze.
 try {
 fNumDrops 
                    = fInData.readInt ();    // drop number
 fNumMeasures 
                    = fInData.readInt (); // Number of measurements
 // 
                    Write the data as an position/time pair
 for 
                    (int i=0; i < fNumMeasures; i++) {
 fData[0][i] 
                    = fInData.readDouble (); // positions
 fData[1][i] 
                    = fInData.readDouble (); // times
 }
 fInputStatus 
                    = InputStatus.EVENT_READ;
 }
 catch (EOFException 
                    eof) {
 fInputStatus 
                    = InputStatus.EOF;
 inputFromFile 
                    (InputCmd.OUT_CLOSE);
 }
 catch (IOException 
                    e) {
 JOptionPane.showMessageDialog 
                    (
 null,
 "I/O 
                    failure", "File Read Error",
 JOptionPane.ERROR_MESSAGE);
 fInputStatus 
                    = InputStatus.ERROR;
 inputFromFile 
                    (InputCmd.OUT_CLOSE);
 }
 break;
 
 case OUT_CLOSE:
 // Close file 
                    when finished with it.
 try {
 fInData.close 
                    ();
 }
 catch (IOException 
                    e) {
 JOptionPane.showMessageDialog 
                    (
 null,
 "I/O 
                    failure on file close!", "File Read Error",
 JOptionPane.ERROR_MESSAGE);
 }
 break;
 }
 
 } // inputFromFile
 
 
 /**
 * Use a JFileChooser in Open mode 
                    to select fFiles
 * to open. Use a filter for FileFilter 
                    subclass to select
 * for *.dat fFiles. If a file is selected 
                    then read the
 * file and place the string into the 
                    textarea.
 **/
 boolean openFile () {
 
 JFileChooser fc = new JFileChooser 
                    ();
 fc.setDialogTitle ("Open File");
 
 // Choose only fFiles, not directories
 fc.setFileSelectionMode ( JFileChooser.FILES_ONLY);
 
 // Start in current directory
 fc.setCurrentDirectory (new File ("."));
 
 // Set filter for web pages.
 fc.setFileFilter (fDataFilter);
 
 // Now open chooser
 int result = fc.showOpenDialog (this);
 
 if (result == JFileChooser.CANCEL_OPTION) 
                    {
 return true;
 } else if ( result == JFileChooser.APPROVE_OPTION) 
                    {
 fInFile = 
                    fc.getSelectedFile ();
 String fInFileName 
                    = fInFile.getName ();
 if (fInFileName 
                    != null) {
 fFileTextField.setText (fInFileName);
 inputFromFile (InputCmd.IN_SETUP);
 } else
 return false;
 
 } else {
 return false;
 }
 return true;
 
 } // openfFile
 
 
 } // class DropDataAnalysis
 
 
 /** Class to use with JFileChooser for selecting hypertext 
                    fFiles.*/
 class DataFilter extends javax.swing.filechooser.FileFilter 
                    {
 
 public boolean accept (File f) {
 return f.getName ().toLowerCase ().endsWith 
                    (".dat")
 || f.isDirectory 
                    ();
 }
 public String getDescription () {
 return "Data files  (*.data)";
 }
 } // class DataFilter
 |      References & Web Resources   Most recent update: Oct. 29, 2005 |