| One last version of our histogram interface will allow for display 
              of the histogram contents as points with error bars instead of vertical 
              columns. We use the class HistogramStatR1 
              (see Refactoring), which includes the 
              following methods that deal with the error values for each bin: 
             
              double [] getBinErrors()- 
                access to the bin error values for all binsdouble getBinError(int 
                bin) - access to the error value for a particular binvoid makeBinErrors() 
                - create error values for each bin using error=sqrt(# 
                entries) boolean packErrors(double 
                [] errors) - set the error values from an array.  The class HistErrPanel 
              , a subclass of PlotPanel, 
              provides for drawing either error bars or the usual columns bars 
              to represent the histogram contents. (It also includes the option 
              of drawing a function over the top of the histogram distribution 
              but we will wait to discuss that in Chapter 
              8: Physics : Histogram Errors & Fits.  In the example below we use these two classes to create a similar 
              applet as that in the Median section. 
              
              
                 
                 
                  |  
                       
                        HistErrorApplet.java 
                        - uses the HistErrPanel to display contents of an 
                        instance of HistogramStatR1. It follows the same basic 
                        form as the Timers demo where 
                        instances of java.util.Timer and java.util.TimerTask update 
                        the display of the histogram during the filling of the 
                        histogram. Includes a "Go" button to initiate the filling 
                        of the histogram. To simulate data taking, a combination 
                        of a Gaussian and random background values are generated. 
                        The number of values come from an entry in a text field. 
                        
 + New 
                        class: HistErrPanel.java 
                        - Display the histogram data with the option of points 
                        and error bars in addition to the usual bin column type 
                        display. It is a subclass of PlotPanel.
 
 + Previous classes:
 Chapter 
                        8:Tech: HistogramStatR1.java,
 Chapter 
                        8:Tech:  
                        MakeData.java, Updateable.java
 Chapter 
                        7:Tech: HistogramStat.java,
 Chapter 
                        6:Tech: Histogram.java, 
                        HistPanel.java
 Chapter 
                        6:Tech: DrawFunction.java
 Chapter 
                        6:Tech: PlotPanel.java, 
                        PlotFormat.java
 
 |   
                  | import 
                    java.awt.*; import javax.swing.*;
 
 /**
 *  Display the histogram data. Subclass of PlotPanel 
                    that
 *  provides the option of drawing error bars.
 */
 public class HistErrPanel extends PlotPanel
 {
 // Histogram access
 protected Histogram fHistogram;
 
 // Flags values to indicate type of bin display
 public final static int DRAW_BARS     
                    = 0;
 public final static int DRAW_PTS      = 
                    1;
 public final static int DRAW_PTS_ERRS = 2;
 int fDrawType = DRAW_BARS;
 
 // Color settings for the bin display
 Color fSymColor      = 
                    Color.BLUE;
 Color fErrorBarColor = Color.BLUE;
 
 protected Color fBarLineColor = Color.DARK_GRAY;
 protected Color fBarFillColor = Color.PINK;
 int gap = 2; // 2 pixels between bars
 
 // Include the option to draw a function on the 
                    panel
 DrawFunction [] fDrawFunctions = null;
 boolean fDrawFunctionFlag = false;
 
 // Fractional margin between highest bar and top 
                    frame
 double fTopMargin  = 0.05;
 // Fractional margnin between side bars and frame
 double fSideMargin = 0.01;
 
 // Arrays to hold the numbers for the axes scale.
 double [] fXScaleValue;
 double [] fYScaleValue;
 
 // Number of values to put on each axis.
 int fNumYScaleValues = 2;
 int fNumXScaleValues = 5;
 
 // Symbol types for plotting points
 public final static int RECT     
                    = 0;
 public final static int RECTFILL = 1;
 public final static int OVAL     
                    = 2;
 public final static int OVALFILL = 3;
 // Set default symbol to filled oval.
 int fSymbolType = OVALFILL;
 
 /**  Create the panel with the histogram. 
                    **/
 public HistErrPanel (Histogram histogram) {
 fHistogram = histogram;
 getScaling ();
 } // ctor
 
 /**
 * Create the panel with the histogram 
                    and pass array
 * of functions to draw over the histogram 
                    plot.
 **/
 public HistErrPanel (Histogram histogram,
 DrawFunction 
                    [] fDrawFunctions) {
 fHistogram = histogram;
 getScaling ();
 
 // Option of drawing on top of the 
                    histogram.
 if ( fDrawFunctions != null){
 this.fDrawFunctions 
                    = fDrawFunctions;
 fDrawFunctionFlag 
                    = true;
 }
 } // ctor
 
 /** Switch to a new histogram. **/
 public void setHistogram (Histogram histogram) 
                    {
 fHistogram = histogram;
 getScaling ();
 repaint ();
 } // setHistogram
 
 /**
 * Get the values for putting scaling 
                    numbers on
 * the plot axes.
 **/
 void getScaling () {
 fYScaleValue = new double[fNumYScaleValues];
 // Use lowest value of 0;
 fYScaleValue[0] = 0.0;
 
 fXScaleValue = new double[fNumXScaleValues];
 // First get the low and high values;
 fXScaleValue[0] = fHistogram.getLo 
                    ();
 fXScaleValue[fNumXScaleValues-1] = 
                    fHistogram.getHi ();
 
 // Then calculate the difference between 
                    the values
 //  (assumes linear scale)
 double range = fXScaleValue[fNumXScaleValues-1] 
                    -
 fXScaleValue[0];
 double dx = range/ (fNumXScaleValues-1);
 
 // Now set the intermediate scale 
                    values.
 for (int i=1; i <  (fNumXScaleValues-1); 
                    i++) {
 fXScaleValue[i] 
                    = i*dx + fXScaleValue[0];
 }
 } // getScaling
 
 /** Optional bar color settings. **/
 public void setBarColors (Color line, Color fill) 
                    {
 if ( line != null) fBarLineColor = 
                    line;
 if ( fill != null) fBarFillColor = 
                    fill;
 }
 
 /** Optional symbol color settings. **/
 public void setSymColors (Color color) {
 if ( color != null) fSymColor=color;
 }
 
 /**
 * Overrides the abstract method in 
                    PlotPanel superclass.
 * Draw the vertical bars that represent 
                    the bin contents.
 * Draw also the numbers for the scales 
                    on the axes.
 **/
 void paintContents (Graphics g) {
 // Get the histogram max value and 
                    bin data
 int maxDataValue = fHistogram.getMax 
                    ();
 
 // Ignore if no data in the histogram.
 // Assumes no negative contents.
 if (maxDataValue == 0) return;
 
 // Make vertical room for error bars
 if (fDrawType == DRAW_PTS_ERRS) {
 // Use estimate 
                    of the error bar for max value
 maxDataValue 
                    += Math.sqrt (maxDataValue);
 }
 
 // Get the histogram bin array.
 int [] bins = fHistogram.getBins ();
 
 // Remember foreground color for later
 Color oldColor = g.getColor ();
 
 // Choose to draw bins as either points 
                    with or without error bars
 // or vertical column bars.
 switch (fDrawType) {
 case DRAW_PTS:
 case DRAW_PTS_ERRS:
 drawPoints 
                    (g,bins,maxDataValue);
 break;
 
 case DRAW_BARS:
 default:
 drawBars (g,bins,maxDataValue);
 break;
 }
 
 // Draw the numbers along the axes
 drawAxesNumbers (g, fXScaleValue, 
                    fYScaleValue);
 
 // Draw the overlay functions
 if (fDrawFunctionFlag) {
 for (int i=0; 
                    i < fDrawFunctions.length; i++){
 fDrawFunctions[i].draw 
                    (
 g,
 fFrameX,     
                    fFrameY,
 fFrameWidth, 
                    fFrameHeight,
 fXScaleValue,fYScaleValue);
 }
 }
 g.setColor (oldColor); //reset original 
                    color
 
 } // paintContents
 
 /**
 * Draw vertical bars to represent 
                    the histogram
 * bin contents.
 * @param g graphics context
 * @param bins histogram array
 * @param maxDataValue the large bin 
                    value. Used to set
 * the scale of the histogram.
 **/
 void drawBars (Graphics g, int [] bins, int max_data_value) 
                    {
 // Find the left margin width.
 int side_space =  (int)(fFrameWidth*fSideMargin);
 
 // Find the width of the frame within 
                    which to draw
 // the bars.
 // Leave room for gaps between frame 
                    and the sides of
 // the first and last bars.
 int draw_width= fFrameWidth - 2 * 
                    side_space -
 (bins.length-1) 
                    * gap;
 
 // Leave a gap between top of tallest 
                    bar and the frame.
 int draw_height=  (int)(fFrameHeight* 
                    (1.0 - fTopMargin));
 
 // Calculate step size between adjacent 
                    bars.
 // To avoid build up of roundoff errors, 
                    the bar
 // positions will be calculated from 
                    a FP value.
 float step_width= (float)draw_width/(float)bins.length;
 int bar_width = Math.round (step_width);
 step_width += gap;
 
 // Scale the bars to the maximum bin 
                    value.
 float scale_factor= (float)draw_height/max_data_value;
 
 // Starting horizontal point on left 
                    hand side.
 int start_x = fFrameX + side_space;
 // Starting vertical point on bottom 
                    left of frame
 int start_y = fFrameY + fFrameHeight;
 
 for (int i=0; i < bins.length; i++) 
                    {
 int bar_height 
                    =  (int) (bins[i] * scale_factor);
 
 int bar_x 
                    =  (int)(i*step_width) + start_x;
 
 // Bar drawn 
                    from top left corner
 int bar_y= 
                    start_y - bar_height;
 
 g.setColor 
                    (fBarLineColor);
 g.drawRect 
                    (bar_x, bar_y, bar_width, bar_height);
 
 g.setColor 
                    (fBarFillColor);
 g.fillRect 
                    (bar_x+1, bar_y+1, bar_width-2, bar_height-1);
 }
 
 // Find the scale value of the full 
                    frame height.
 fYScaleValue[fYScaleValue.length-1] 
                    =
 (double)(fFrameHeight/scale_factor);
 
 } // drawBars
 
 /**
 *  Draw points instead of 
                    column bars for the histogram contents.
 *  Option to include error 
                    bars.
 **/
 void drawPoints (Graphics g, int [] bins, int 
                    max_data_value) {
 // If error bars on the points requested, 
                    then
 // obtain the error array.
 double [] err_y = null;
 if (fDrawType == DRAW_PTS_ERRS) {
 // Get the histogram error 
                    array. If the histogram is
 // not the HistogramStatR1 
                    subclass, an exception will occur
 // here.
 if (fHistogram instanceof 
                    HistogramStatR1){
 err_y 
                    =  ( (HistogramStatR1)fHistogram).getBinErrors ();
 if 
                    (err_y == null) return;
 } else
 return;
 }
 
 // Find the left margin width.
 int side_space =  (int) 
                    (fFrameWidth*fSideMargin);
 
 // For data symbols get size relative 
                    to the frame.
 int sym_dim =  (int) (fFrameWidth 
                    *.01);
 
 // Leave a gap between top of tallest 
                    bar and the frame.
 int draw_height=  (int) 
                    (fFrameHeight* (1.0 - fTopMargin));
 
 // Scale the data points to the maximum 
                    bin value.
 float scale_factor= (float)draw_height/max_data_value;
 
 // Calculate step size between adjacent 
                    points.
 // To avoid build up of roundoff errors, 
                    the point
 // positions will be calculated from 
                    a FP value.
 float step_width= (float)fFrameWidth/ 
                    (float)bins.length;
 
 // Calculate starting point horizontally. 
                    Put points
 // in middle of bin.
 int start_x = Math.round (step_width/2) 
                    + fFrameX;
 // Starting vertical point on bottom 
                    left of frame
 int start_y = fFrameY + fFrameHeight;
 
 // Use half the width of a bin as 
                    the x error bar.
 int x_error_bar = fFrameWidth/(2 * 
                    bins.length);
 
 for (int i=0; i < bins.length; i++) 
                    {
 int x =  (int) 
                    (i * step_width)+start_x;
 int y = start_y -  (int) 
                    (bins[i] * scale_factor);
 
 // Draw data point symbols
 g.setColor (fSymColor);
 switch  (fSymbolType) 
                    {
 case RECT 
                    :
 g.drawRect 
                    (x-sym_dim, y-sym_dim, 2*sym_dim, 2*sym_dim);
 break;
 
 case RECTFILL 
                    :
 g.fillRect 
                    (x-sym_dim, y-sym_dim, 2*sym_dim+1, 2*sym_dim+1);
 break;
 
 case OVAL 
                    :
 g.drawOval 
                    (x-sym_dim, y-sym_dim, 2*sym_dim, 2*sym_dim);
 break;
 
 case OVALFILL 
                    :
 default :
 g.fillOval 
                    (x-sym_dim, y-sym_dim, 2*sym_dim+1, 2*sym_dim+1);
 break;
 }
 
 g.setColor (fErrorBarColor);
 
 if (fDrawType == DRAW_PTS_ERRS) 
                    {
 // 
                    Draw x error bar as bin width.
 g.drawLine 
                    (x-x_error_bar,y,x+x_error_bar,y);
 
 if 
                    (err_y != null) {
 int 
                    y_bar =  (int)(err_y[i] * scale_factor/2.0);
 // 
                    Draw y error bars but keep within the
 // 
                    frame.
 int 
                    dy_up = y - y_bar;
 if 
                    (dy_up < fFrameY) dy_up = fFrameY;
 int 
                    dy_down = y + y_bar;
 if 
                    (dy_down > start_y) dy_down = start_y;
 g.drawLine 
                    (x, dy_up, x, dy_down);
 }
 }
 }
 // Find the scale value of the full 
                    frame height.
 fYScaleValue[fYScaleValue.length-1] 
                    =
 (double)(fFrameHeight/scale_factor);
 
 } // drawPoints
 
 // Methods overriding those in PlotPanel
 String getTitle ()
 {  return fHistogram.getTitle ();}
 
 String getXLabel ()
 {  return fHistogram.getXLabel ();}
 
 /**
 *  Set type of symbol to 
                    use for a point in the plot.
 *  @param type set to one 
                    of the class constants.
 **/
 void setSymbolType (int type) {
 if (type < 0 || type > 3) return;
 fSymbolType = type;
 }
 
 /** Set flag for drawing the error bars or not. 
                    **/
 void setDrawType (int drawType) {
 fDrawType = drawType;
 }
 
 /**
 *  Pass object to array 
                    of functions to draw over
 *  the histogram distributions.
 **/
 void setDrawFunction ( DrawFunction [] functions) 
                    {
 fDrawFunctions = functions;
 }
 
 /** Pass flag to draw a function overlay. **/
 void setDrawFunctionEnabled (boolean flag) {
 fDrawFunctionFlag = flag;
 // Don't enable if no function available.
 // Could throw an exception or a 
                    warning dialog here.
 //if ( drawFunction = null) fDrawFunctionFlag 
                    = false;
 
 } // setDrawFunctionEnabled
 
 } // class HistErrPanel
 |   
                  | import 
                      javax.swing.*;import java.awt.*;
 import java.awt.event.*;
 
 /**
 * This program will run as an applet inside
 * an application frame.
 *
 *  The applet uses the HistErrPanel 
                      to display contents of
 *  an instance of HistogramStatR1.
 *
 * The java.util.Timer and java.util.TimerTask 
                      are used
 * to update the display of the histogram during 
                      the filling
 * of the histogram.
 *
 * Includes "Go" button to initiate the filling 
                      of the histogram.
 * To simulate data taking, a combination of 
                      a Gaussian and random
 * background values are generated.
 *
 * The number of values taken from
 * entry in a JTextField. "Clear"  button 
                      clears the histogram.
 * In standalone mode, the Exit button closes 
                      the program.
 *
 **/
 public class HistErrorApplet extends JApplet
 implements ActionListener, Updateable
 {
 // Use the HistPanel JPanel subclass here
 HistErrPanel fOutputPanel;
 
 HistogramStatR1 histogram;
 
 boolean fMakingHist    = 
                      false;
 boolean fUpdateDisplay = false;
 MakeData fMakeData;
 int fNumDataPoints=100;
 
 // Use the java.util Timer and TimerTask combo
 // for timing events.
 java.util.Timer fTimer;
 
 // A text field for input strings
 JTextField fTextField;
 
 // Flag for whether the applet is in a browser
 // or running via the main () below.
 boolean fInBrowser = true;
 
 int fDrawType = HistErrPanel.DRAW_PTS_ERRS;
 
 // Buttons
 JButton fGoButton;
 JButton fStatsButton;
 JButton fClearButton;
 JButton fExitButton;
 
 /**
 * Create a User Interface with a 
                      histogram and a Go button
 * to initiate processing and a Clear 
                      button to clear the .
 * histogram. In application mode, 
                      the Exit button stops the
 * program. Add a stats button to 
                      open a frame window to show
 *  statistical measures.
 **/
 public void init () {
 
 Container content_pane = getContentPane 
                      ();
 
 JPanel panel = new JPanel (new BorderLayout 
                      ());
 
 // Use a textfield for an input 
                      parameter.
 fTextField =
 new JTextField (Integer.toString 
                      (fNumDataPoints), 10);
 
 // If return hit after entering 
                      text, the
 // actionPerformed will be invoked.
 fTextField.addActionListener (this);
 
 fGoButton = new JButton ("Go");
 fGoButton.addActionListener (this);
 
 fStatsButton = new JButton ("Stats");
 fStatsButton.addActionListener (this);
 
 fClearButton = new JButton ("Clear");
 fClearButton.addActionListener (this);
 
 fExitButton = new JButton ("Exit");
 fExitButton.addActionListener (this);
 
 JPanel control_panel = new JPanel 
                      ();
 
 control_panel.add (fTextField);
 control_panel.add (fGoButton);
 control_panel.add (fStatsButton);
 control_panel.add (fClearButton);
 control_panel.add (fExitButton);
 
 // Create a histogram and start 
                      filling it.
 makeHist ();
 fGoButton.setText ("Stop");
 fClearButton.setEnabled (false);
 fStatsButton.setEnabled (false);
 if (fInBrowser) fExitButton.setEnabled 
                      (false);
 
 // JPanel subclass here.
 fOutputPanel = new HistErrPanel 
                      (histogram);
 fOutputPanel.setDrawType (fDrawType);
 
 panel.add (fOutputPanel,"Center");
 panel.add (control_panel,"South");
 
 // Add text area with scrolling 
                      to the contentPane.
 content_pane.add (panel);
 
 } // init
 
 public void actionPerformed (ActionEvent e) 
                      {
 Object source = e.getSource ();
 if (source == fGoButton || source 
                      == fTextField) {
 String strNumDataPoints 
                      = fTextField.getText ();
 try {
 fNumDataPoints 
                      = Integer.parseInt (strNumDataPoints);
 }
 catch (NumberFormatException 
                      ex) {
 // 
                      Could open an error dialog here but just
 // 
                      display a message on the browser status line.
 showStatus 
                      ("Bad input value");
 return;
 }
 if (!fMakingHist) 
                      {
 makeHist ();
 fGoButton.setText ("Stop");
 fStatsButton.setEnabled (false);
 fClearButton.setEnabled (false);
 } else {
 // Stop button has been pushed
 fGoButton.setText ("Go");
 fStatsButton.setEnabled (true);
 fClearButton.setEnabled (true);
 fMakingHist = false;
 }
 
 } else if (source == fStatsButton) 
                      {
 displayStats 
                      ();
 
 } else if (source == fClearButton) 
                      {
 // Clear the histogram
 histogram.clear ();
 repaint ();
 
 } else if (!fInBrowser)
 System.exit 
                      (0);
 
 } // actionPerformed
 
 /** Create a frame to display the distribution 
                      statistics. **/
 void displayStats () {
 JFrame frame =
 new JFrame 
                      ("Histogram Distributions Statistics");
 frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
 
 JTextArea area = new JTextArea ();
 
 double [] stats = histogram.getStats 
                      ();
 if (stats != null) {
 area.append ("Number 
                      entries = " + histogram.getTotal ()+"\n");
 
 String stat = PlotFormat.getFormatted 
                      (
 stats[HistogramStatR1.I_MEDIAN],
 1000.0,0.001,3);
 area.append ("Median 
                      value = "+ stat +" "+"\n");
 
 stat = PlotFormat.getFormatted 
                      (
 stats[HistogramStatR1.I_MEAN],
 1000.0,0.001,3);
 area.append ("Mean value 
                      = "+ stat +" ");
 
 stat = PlotFormat.getFormatted 
                      (
 stats[HistogramStatR1.I_MEAN_ERROR],
 1000.0,0.001,3);
 area.append (" +/- "+stat+"\n");
 
 stat = PlotFormat.getFormatted 
                      (
 stats[HistogramStatR1.I_STD_DEV],
 1000.0,0.001,3);
 area.append ("Std. Dev. 
                      = "+stat+"\n");
 
 stat = PlotFormat.getFormatted 
                      (
 stats[HistogramStatR1.I_SKEWNESS],
 1000.0,0.001,3);
 area.append ("Skewness 
                      = "+stat+"\n");
 
 stat = PlotFormat.getFormatted 
                      (
 stats[HistogramStatR1.I_KURTOSIS],
 1000.0,0.001,3);
 area.append ("Kurtosis 
                      = "+stat+"\n");
 }  else {
 area.setText ("No statistical 
                      information available");
 }
 
 frame.getContentPane ().add (area);
 frame.setSize (200,200);
 frame.setVisible (true);;
 } // displayStats
 
 /**
 *  Create the histogram, 
                      create the MakeData instance and
 *  spin it off in a thread. 
                      Set up a java.util.Timer to
 *  run the PaintHistTask 
                      periodically.
 **/
 void makeHist () {
 if (fMakingHist) return; // only 
                      fill one hist at a time.
 fMakingHist 
                      = true;
 
 // Create an instance of the histogram 
                      class.
 // Make it wide enough enough to 
                      include the data.
 if (histogram == null)
 histogram 
                      = new HistogramStatR1 ("Gaussian + Random Background",
 "Data", 
                      20,-10.0,10.0);
 
 // Create the runnable object to 
                      fill the histogram
 // Center signal at 3.0 and create 
                      background between
 // -10 and 10. The fraction of the 
                      data due to the
 // Gaussian will be 0.60. The maximum 
                      delay between
 // data poins will be 500msecs.
 fMakeData =
 new MakeData (this, 
                      histogram, fNumDataPoints,
 3.0, 0.60, -10.0, 10.0, 500);
 Thread data_thread = new Thread 
                      (fMakeData);
 
 // Before starting the filling, 
                      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 ();
 
 // Start the timer after 100ms and 
                      then repeat calls
 // to run in PaintHistTask object 
                      every 250ms.
 fTimer.schedule (new PaintHistTask 
                      (), 100, 250);
 
 // Now start the data filling.
 data_thread.start ();
 
 } // makeHist
 
 /**
 * Use the inner class technique to define the
 * TimerTask subclass for signalling that the 
                      display
 * should be updated.
 */
 class PaintHistTask extends java.util.TimerTask
 {
 public void run () {
 if (fDrawType == HistErrPanel.DRAW_PTS_ERRS)
 histogram.makeBinErrors ();
 fUpdateDisplay = true;
 }
 } // class PaintHistTask
 
 /**
 *  Repaint the histogram 
                      display. If called by
 *  the MakeData object, 
                      it will turn off the
 *  update display flag 
                      and return the fMakingHist flag
 *  to indicate if updating 
                      should continue.
 
 
 **/
 public boolean update (Object obj) {
 
 // Don't update the display until 
                      the timer
 // turns on the fUpdateDisplay flag.
 if ( fUpdateDisplay) {
 // Possible this method 
                      called before fOutputPanel
 // created in the init 
                      (). So check if it exists
 // before attempting 
                      to repaint.
 if (fOutputPanel != 
                      null) {
 // Now 
                      rescale and draw.
 fOutputPanel.getScaling 
                      ();
 fOutputPanel.repaint 
                      ();
 }
 fUpdateDisplay = false;
 }
 return fMakingHist;
 } // update
 
 /** Called when the histogram filling is finished. 
                      **/
 public void done () {
 fMakingHist = false;
 
 // Stop the histogram display updates.
 fTimer.cancel ();
 
 fOutputPanel.getScaling ();
 fOutputPanel.repaint ();
 
 // Reset the buttons.
 fGoButton.setText ("Go");
 
 fGoButton.setEnabled (true);
 fStatsButton.setEnabled (true);
 fClearButton.setEnabled (true);
 
 } // done
 
 public static void main (String[] args) {
 //
 int frame_width=450;
 int frame_height=300;
 
 // Create an instance of the applet 
                      and display it on a frame.
 HistErrorApplet applet = new HistErrorApplet 
                      ();
 applet.fInBrowser = false;
 applet.init ();
 
 // Following anonymous class used 
                      to close window & exit program
 JFrame f = new JFrame ("Demo");
 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
 
 } // class HistErrorApplet
 |    References 
              & Web Resources Last update: Nov. 8, 2004 |