// "Java Tech"
// Code provided with book for educational purposes only.
// No warranty or guarantee implied.
// This code freely available. No copyright claimed.
// 2003
//
// Begin with StartJApplet11.java
/*
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/**
* Demonstrate Java sorting tools by applying them to histogram
* bin values.
*
* This program will run as an applet inside an application frame.
*
* The applet uses the HistPanel to display contents of
* an instance of Histogram. HistFormat used by HistPanel to
* format the scale values.
*
* 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 SortHistFillApplet extends JApplet
implements ActionListener, Updateable
{
// Use the HistPanel JPanel subclass here
HistPanel fOutputPanel;
Histogram fHistogram;
int fNumDataPoints = 100;
boolean fMakingHist = false;
boolean fUpdateDisplay = false;
MakeData fMakeData;
// Use the java.util Timer and TimerTask combo
// for timing events.
java.util.Timer fTimer;
// Reference to sorting object.
Sorter fSorter;
// A text field for input strings
JTextField fTextField = null;
// Flag for whether the applet is in a browser
// or running via the main () below.
boolean fInBrowser = true;
//Buttons
JButton fGoButton;
JButton fSortButton;
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.
**/
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);
fSortButton = new JButton ("Sort");
fSortButton.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 (fSortButton);
control_panel.add (fClearButton);
control_panel.add (fExitButton);
// Create a histogram and start filling it.
makeHist ();
fGoButton.setText ("Stop");
fClearButton.setEnabled (false);
fSortButton.setEnabled (false);
if (fInBrowser) fExitButton.setEnabled (false);
// JPanel subclass here.
fOutputPanel = new HistPanel (fHistogram);
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");
fSortButton.setEnabled (false);
fClearButton.setEnabled (false);
} else {
// Stop button has been pushed
fGoButton.setText ("Go");
fSortButton.setEnabled (true);
fClearButton.setEnabled (true);
fMakingHist = false;
}
} else if (source == fSortButton) {
if (fSorter == null) {
fSortButton.setText ("Stop");
fGoButton.setEnabled (false);
fClearButton.setEnabled (false);
fSorter = new BubbleSorter (this, fHistogram.getBins ());
fSorter.start ();
} else { // Stop button pushed
fSorter = null;
fSortButton.setText ("Sort");
fGoButton.setEnabled (true);
fClearButton.setEnabled (true);
}
} else if (source == fClearButton) {
fHistogram.clear ();
repaint ();
} else if (!fInBrowser)
System.exit (0);
} // actionPerformed
/**
* 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 (fHistogram == null)
fHistogram = new Histogram ("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, fHistogram, 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 () {
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.
* If called by a Sorter object, it will repaint the
* panel and the pause briefly so that the display
* will give a nice animation of the sorting.
*/
public boolean update (Object obj) {
// For sorting, always repaint the output.
if (obj instanceof Sorter) {
fOutputPanel.repaint ();
try {
Thread.sleep (25);
}
catch (InterruptedException e)
{}
return true;
}
// 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) {
fOutputPanel.getScaling ();
fOutputPanel.repaint ();
}
fUpdateDisplay = false;
}
return fMakingHist;
} // update
/**
* Called when the histogram filling is finished
* and when the sorting is finished.
**/
public void done () {
fMakingHist = false;
fSorter = null;
// Stop the histogram display updates.
fTimer.cancel ();
// Update one last time
fOutputPanel.getScaling ();
fOutputPanel.repaint ();
// Reset the buttons.
fGoButton.setText ("Go");
fSortButton.setText ("Sort");
fGoButton.setEnabled (true);
fSortButton.setEnabled (true);
fClearButton.setEnabled (true);
} // done
public static void main (String[] args) {
//
int frame_width=450;
int frame_height=300;
//
SortHistFillApplet applet = new SortHistFillApplet ();
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 SortFillHistApplet