package mil.navy.nps.logger; // Standard java stuff import java.applet.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.*; import java.lang.Runtime; // Swing stuff import javax.swing.*; import javax.swing.event.*; // DIS stuff and other packages import mil.navy.nps.dis.*; import mil.navy.nps.util.*; import mil.navy.nps.testing.*; import mil.navy.nps.disEnumerations.*; /** * Main class for the PduPlayer application. Creates user interface. * Calls the appropriate methods for each button - play, fast forward, * rewind, stop, record. * @author Millie Ives * @author David Holland * @author DMcG * @version Version 3.0 *
* * Invocation: *
* java mil.navy.nps.logger.PduPlayer
*
or
* c:\vrtp\demo\pduRecordings> PduPlayer.bat
*
or
* unix/vrtp/demo/pduRecordings> PduPlayer.sh
*/
public class PduPlayer extends JFrame //Applet // Panel
{
public static final String DEFAULT_MULTICAST_ADDRESS = "224.2.181.145";
public static final int DEFAULT_PORT = 62040;
public static final int DEFAULT_TTL = 16;
public static final String DEFAULT_FILENAME = "_newRecording.pdu";
protected JPanel drawArea;
protected Frame drawFrame;
// Threads for replay, play, record, etc.
protected Play autoObject = null;
protected Play playObject = null;
protected Record recordObject = null;
protected Rewind rewindObject = null;
protected FFwd ffwdObject = null;
// GUI fields that reflect the state of the logger
protected JSlider pduSlider;
protected JTextField totalPdus;
protected String multicastAddress = DEFAULT_MULTICAST_ADDRESS;
protected int portNo = DEFAULT_PORT;
protected int timeToLive = DEFAULT_TTL;
protected String filename = DEFAULT_FILENAME;
protected BehaviorStreamBufferInfo fileInfo = new BehaviorStreamBufferInfo(false);
transient int state, mode;
transient String msg;
// Menu items for the application
protected MenuItem newMenuItem;
protected MenuItem quitMenuItem;
protected MenuItem openMenuItem;
protected MenuItem saveMenuItem;
protected MenuItem saveAsMenuItem;
protected MenuItem fileInfoMenuItem;
protected MenuItem usersGuideMenuItem;
protected MenuItem aboutMenuItem;
protected MenuItem supportMenuItem;
protected MenuItem toggleModeMenuItem;
protected MenuItem clearPdusMenuItem;
protected MenuItem networkParamsMenuItem;
protected MenuItem editMenuItem;
// Top level menus
transient Menu fileMenu;
transient Menu optionsMenu;
transient Menu helpMenu;
// File open dialog
transient FileDialog file;
// Buffer that holds received pdus.
static Vector pduBuffer = new Vector();
static Scrollbar horizontal; //DEBUG
// Buttons for replay, rewind, other VCR functions
protected JToggleButton rewButton = new JToggleButton ("");
protected JToggleButton playButton = new JToggleButton ("");
protected JToggleButton ffwdButton = new JToggleButton ("");
protected JToggleButton recButton = new JToggleButton ("");
protected JToggleButton stopButton = new JToggleButton ("");
protected JToggleButton autoButton = new JToggleButton ("");
protected ButtonGroup buttonGroup; // Holds the buttons, only one of which can be selected at a time.
protected int pduIndex = 0; // pointer to current pdu
protected int pduCount = 0; // total number of pdus in memory
protected boolean changedFromMethod = false;
// file name and directories
private String directory = "";
// Constants defined to identify various states.
public static final int STOP = 0;
public static final int REWIND = 1;
public static final int PLAY = 2;
public static final int FFWD = 3;
public static final int RECORD = 4;
public static final int AUTOREPEAT = 5;
/**
* Returns the pdu buffer used to record pdus. Contains any type of PDU,
* not limited to just ESPDUs. Any access to the variable should be through
* this method.
*/
public static Vector getPduBuffer()
{ return pduBuffer;
}
public void addPdu(ProtocolDataUnit pPdu)
{
pduBuffer.add(pPdu);
this.syncPduCount();
}
public void syncPduCount()
{
int pduCount = pduBuffer.size();
totalPdus.setText("Total PDUs: " + (new Integer(pduCount)).toString());
}
/**
* Sets the current index of PDUs, the next PDU to be read.
* Also updates the display of the current PDU.
*/
public void setPduIndex(int pNewIndex)
{
int position; // whacked to int value
int bufferSize = pduBuffer.size();
double percentage = (double)pNewIndex / (double)bufferSize;
pduIndex = pNewIndex;
position = (int)(percentage * 100.0);
// We use the boolean to modify the behavior of the sliderChanged method.
changedFromMethod = true;
pduSlider.setValue(position);
changedFromMethod = false;
}
/**
* Returns the current index of PDUs, the index of the next PDU in memory.
*/
public int getPduIndex()
{ return pduIndex;
}
/**
* finds the directory in which the image icons are saved.
*/
private String getImageDirectory()
{
// This has the effect of looking in several directories for the images.
// the first image, the rewind button, is used for a test case to find
// the directory the other images are kept in. there should be a better
// way to do this--my guess would be to return the class path from the
// system properties list, then search the classpath for the files. This
// would allow arbitrary directory placement, rather than in specific
// directory or disk placement.
int idx = 0;
String subdirectory;
String fullPathname; // Full pathname to gif file
String directories[] = {"",
"file:///C|/vrtp/mil/navy/nps/logger/",
"d:/vrtp/mil/navy/nps/logger/",
"/vrtp/mil/navy/nps/logger/",
"/vrtp/mil/navy/nps/logger/",
"c:/work/vrtp/mil/navy/nps/logger/"}; // extra special mcgredo directory
// Loop through the direcotries, looking for one in which the rewind button gif is kept.
while(idx < directories.length)
{
subdirectory = directories[idx];
fullPathname = subdirectory + "images/rew_dn.gif";
ImageIcon rew_dn = new ImageIcon(fullPathname);
if (rew_dn.getImageLoadStatus() == MediaTracker.COMPLETE)
{
return subdirectory;
}
idx++;
}
subdirectory = null;
return subdirectory;
}
/**
* Adds assorted menus to the menu bar.
*/
private void setupMenus()
{
// Set up the top menu bar, the main menus
fileMenu = new Menu("File",true);
optionsMenu = new Menu("Options", true);
helpMenu = new Menu("Help",true);
// File menu additions, using anonymous classes as event handlers.
// New
fileMenu.add(newMenuItem = new MenuItem("New"));
newMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JFrame newWindow;
newWindow = new PduPlayer();
newWindow.setVisible(true);
}
});
// Right. These menus use anonymous inner classes to define event
// handlers for the buttons. The problem is that the mass of code
// here hides what's going on--several button handler anonymous
// classes strung together would run to several pages of code.
// So here we keep the anonymous inner classes as event handlers,
// but simply use them to call dedicated methods in this class instance.
// there's a special syntax for referring to the enclosing instance
// of the inner anonymous class, "PduPlayer.this". This looks like
// a static method call or class variable, reference, but it's not.
// It's a reference to the _instance_ of the class (ie, this instance)
// that encloses the _instance_ of the anonymous class.
// (inner class instances are special in that they can refer to even
// private variables of their enclosing class.)
// Open recorded file. PduPlayer.this refers to this object itself; openFile() is an
// instance method in this object.
fileMenu.add(openMenuItem = new MenuItem("Open"));
openMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
PduPlayer.this.openFile();
}
});
// Save buffer of pdus to a file.
fileMenu.add(saveMenuItem = new MenuItem("Save"));
saveMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
PduPlayer.this.saveFile();
}
});
// Save As menu item.
fileMenu.add(saveAsMenuItem = new MenuItem("Save as"));
saveAsMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
PduPlayer.this.saveAsFile();
}
});
// File info--bring up an editable window with the various
// prepended data from the file included. This is turned
// off until they actually open or save a file.
fileMenu.add(fileInfoMenuItem = new MenuItem("File Info"));
fileInfoMenuItem.setEnabled(false);
fileInfoMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
PduPlayer.this.runPropertiesDialog();
}
});
// Quit menu item. Just Do It.
fileMenu.add(quitMenuItem = new MenuItem("Quit"));
quitMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
// Toggle options in menu that turn modes on or off.
//optionsMenu.add(toggleModeMenuItem = new MenuItem("Mode"));
optionsMenu.add(networkParamsMenuItem = new MenuItem("Network Parameters"));
optionsMenu.add(editMenuItem = new MenuItem("Edit PDUs"));
optionsMenu.add(clearPdusMenuItem = new MenuItem("Clear PDUs"));
// Menu item for clearing out saved up in memory PDUs.
clearPdusMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
pduSlider.setValue(0);
pduBuffer = new Vector();
PduPlayer.this.syncPduCount();
JOptionPane.showMessageDialog(PduPlayer.this, "PDUs cleared and playlist reset.");
}
});
// Run the dialog box that asks the user for networking parameters, such
// as ttl, multicast address, etc.
networkParamsMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
NetworkDialog dialog = new NetworkDialog(PduPlayer.this, multicastAddress, portNo, timeToLive);
dialog.setVisible(true);
// If they hit "OK", get the values from the dialog box that they entered.
if(dialog.getResult() == NetworkDialog.OK)
{
multicastAddress = dialog.getMulticastAddress();
portNo = dialog.getPort();
timeToLive = dialog.getTTL();
}
}
});
editMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
EditFrame editor = new EditFrame(PduPlayer.this);
editor.setTitle("PDU Editing");
editor.setVisible(true);
}
});
// Help menu and user guide menu
helpMenu.add(usersGuideMenuItem = new MenuItem("User's Guide"));
usersGuideMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
PduPlayer.this.helpMenu();
}
});
// Help menu additions. Just Do It.
helpMenu.add(aboutMenuItem = new MenuItem("About PduPlayer"));
aboutMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JOptionPane.showMessageDialog(PduPlayer.this,
"PduPlayer Version 2.0, Updated 12/31/99\nAuthors: Millie Ives, David Holland\nGeorge Mason University");
}
});
// Suport menu item, user's support guide. Just Do It.
helpMenu.add(supportMenuItem = new MenuItem("User's Guide Support"));
supportMenuItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JOptionPane.showMessageDialog(PduPlayer.this,
"Note: You must close all Netscape windows\nto pull up the support page.");
}
});
// Add the menu bar; put all the menus in, then add the menu bar to the application.
MenuBar mb = new MenuBar();
mb.add (fileMenu);
mb.add (optionsMenu);
mb.add (helpMenu);
this.setMenuBar(mb);
}
/**
* Adds buttons to the application with the correct icons in them
*/
private void createButtons()
{
directory = this.getImageDirectory();
// found the image and the directory the live in. Load all the images.
ImageIcon rew_dn = new ImageIcon(directory + "images/rew_dn.gif");
ImageIcon rew_up = new ImageIcon(directory + "images/rew_up.gif");
ImageIcon play_dn = new ImageIcon(directory + "images/play_dn.gif");
ImageIcon play_up = new ImageIcon(directory + "images/play_up.gif");
ImageIcon ffwd_dn = new ImageIcon(directory + "images/ffwd_dn.gif");
ImageIcon ffwd_up = new ImageIcon(directory + "images/ffwd_up.gif");
ImageIcon rec_dn = new ImageIcon(directory + "images/rec_dn.gif");
ImageIcon rec_up = new ImageIcon(directory + "images/rec_up.gif");
ImageIcon stop_dn = new ImageIcon(directory + "images/stop_dn.gif");
ImageIcon stop_up = new ImageIcon(directory + "images/stop_up.gif");
ImageIcon auto_dn = new ImageIcon(directory + "images/auto_dn.gif");
ImageIcon auto_up = new ImageIcon(directory + "images/auto_up.gif");
// Fire up the button, with the loaded image. Rewind.
rewButton.setIcon(rew_up);
rewButton.setSelectedIcon(rew_dn);
rewButton.setDisabledIcon(rew_up);
// Play button
playButton.setIcon(play_up);
playButton.setSelectedIcon(play_dn);
playButton.setDisabledIcon(play_up);
// fast forward button
ffwdButton.setIcon(ffwd_up);
ffwdButton.setSelectedIcon(ffwd_dn);
ffwdButton.setDisabledIcon(ffwd_up);
// Record button
recButton.setIcon(rec_up);
recButton.setSelectedIcon(rec_dn);
recButton.setDisabledIcon(rec_up);
// Stop button
stopButton.setIcon(stop_up);
stopButton.setSelectedIcon(stop_dn);
stopButton.setDisabledIcon(stop_up);
stopButton.setSelected(true);
// auto button
autoButton.setIcon(auto_up);
autoButton.setSelectedIcon(auto_dn);
autoButton.setDisabledIcon(auto_up);
// All the buttons are put in a button group, only one of which can be
// selected at a time.
buttonGroup = new ButtonGroup();
buttonGroup.add(rewButton);
buttonGroup.add(playButton);
buttonGroup.add(ffwdButton);
buttonGroup.add(recButton);
buttonGroup.add(stopButton);
buttonGroup.add(autoButton);
}
/**
* Constructor for the PDU logger.
*/
public PduPlayer()
{
// Set up action handler for window close. This shuts down the
// threads that may be running.
this.addWindowListener( new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
PduPlayer.this.performStopButtonHit();
pduBuffer = new Vector(); // maybe speed up GC a bit
}
});
// Lays out buttons and meters.
this.createButtons();
this.setupMenus();
// Text fields that reflect various options for user entry or to reflect
// current state.
totalPdus = new JTextField(12); // total number of PDUs loaded
totalPdus.setEditable(false); // user no touchee with grubby fingers
pduSlider = new JSlider(); // Slider for current PDU position
pduSlider.setValue(0); // move slider all the way to the left
// Set up labels for the slider
Hashtable labelTable = new Hashtable();
labelTable.put( new Integer( 0 ), new JLabel("0%") );
labelTable.put( new Integer( 50 ), new JLabel("50%") );
labelTable.put( new Integer( 100 ), new JLabel("100%") );
pduSlider.setLabelTable( labelTable );
pduSlider.setPaintLabels(true);
pduSlider.setBorder(BorderFactory.createEmptyBorder(0,0,0,10));
// Tick marks for slider
pduSlider.setMajorTickSpacing(25);
pduSlider.setMinorTickSpacing(5);
pduSlider.setPaintTicks(true);
// Set up change listener for the slider. This is called whenever the
// slider is dragged.
pduSlider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e)
{
int sliderValue = pduSlider.getValue(); // value from zero to 100
int bufferSize = pduBuffer.size();
double percentage = ((double)sliderValue / 100.0);
// set the current PDU position based on the position of the slider
if(changedFromMethod == false)
{
pduIndex = (int)(bufferSize * percentage);
//System.out.println("new index is " + pduIndex);
}
}
});
// Begin constructing the GUI. Lay out buttons, etc. These use anonymous classes
// as action handlers for the button.
drawArea = new JPanel();
drawArea.setLayout(new BorderLayout() );
// Set up the left panel.
Panel left = new Panel();
left.setLayout(new GridLayout(2,1));
left.add(totalPdus);
left.add(new Label("PDU Position"));
drawArea.add("West", left);
// Set up the right panel.
Panel right = new Panel();
right.setLayout(new GridLayout(2,1));
//right.add(fileName);
right.add(new JLabel(" ")); // Filler to keep alignment nice
right.add(pduSlider);
drawArea.add("East",right);
//right.add(pduLocation);
// Set up the bottom row of buttons.
Panel parent = new Panel ();
parent.setLayout(new BorderLayout());
Panel p = new Panel();
p.setLayout(new FlowLayout());
parent.add("North",p);
p.add(rewButton);
// The rewind, ffwd, stop, etc buttons are set up in a ButtonGroup.
// A buttonGroup can have only one button selected at any one time.
// The button group also handles sending select and deselect messages
// to all the members of the button group, so that clicking on
// another button automatically does all the scut work of picking
// a new button and deselecting the old one. We have to implement
// two handlers here, one for actions (actionListener) and one for
// ItemSelection, which turns buttons on and off.
// Action listener for rewind button
rewButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
PduPlayer.this.rewindButtonHit();
}
});
// The item selection button for the rewind button; called when the item
// button selection changes.
rewButton.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
if (e.getStateChange() != ItemEvent.SELECTED)
{
rewindObject.setRunDone(true);
}
}
});
// Play button. Play the items in the in-memory buffer, possibly
// augmented by more PDUs from the file.
p.add(playButton);
playButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
PduPlayer.this.playButtonHit();
}
});
// play button item selection
playButton.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
if (e.getStateChange() != ItemEvent.SELECTED)
{
System.out.println("play button deselected");
playObject.setRunDone(true);
}
}
});
p.add(ffwdButton);
ffwdButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
PduPlayer.this.ffwdButtonHit();
}
});
// ffwd button item selection
ffwdButton.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
if (e.getStateChange() != ItemEvent.SELECTED)
{
ffwdObject.setRunDone(true);
}
}
});
p.add(recButton);
recButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
PduPlayer.this.recordButtonHit();
System.out.println ("Record...");
}
});
// button selection/deselection, called automatically by button group
recButton.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
if (e.getStateChange() != ItemEvent.SELECTED)
{
recordObject.setStillRunning(false);
}
}
});
// Stop button actions. What happens here is not really important; the
// shutdown of whatever was going on (play, record, whatever) when this
// button was hit is handled in the item selection code of the appropriate
// button. In other words, the logic for shutdown is in the state transition
// from the other button, not here.
p.add(stopButton);
stopButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.out.println ("Stop.");
}
});
stopButton.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
if (e.getStateChange() == ItemEvent.SELECTED)
{
System.out.println("stop button selected");
}
else
{
System.out.println("stop button deselected");
}
}
});
// Auto button
p.add(autoButton);
autoButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
PduPlayer.this.autoButtonHit();
}
});
autoButton.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
if (e.getStateChange() != ItemEvent.SELECTED)
{
//recButton.setSelected(false);
autoObject.setRunDone(true);
}
}
});
drawArea.add("South",parent);
// Put it all together.
this.setTitle("PduPlayer " + filename);
this.getContentPane().add(drawArea);
this.setSize(385,150);
this.syncPduCount();
this.setVisible(true);
}
/**
* Handles an "openFile" event. Called from the anonymous inner class
* created in the constructor.
*/
public void openFile()
{
BehaviorStreamBufferFile bsbf;
ProtocolDataUnit pdu;
// Run a file dialog panel to get the file to open.
// Run a file dialog box to get the pathname to the PDU file the user wants to open.
msg = "Open File";
file = new FileDialog(PduPlayer.this, msg, state);
file.setDirectory("C:\\vrtp\\demo\\pduRecordings");
file.show();
String currFile, tempstr = "";
if( (currFile = file.getFile()) != null)
{
tempstr = currFile;
filename = tempstr;
this.setTitle("PduPlayer: " + filename);
pduBuffer = new Vector();
this.setPduIndex(0);
}
try
{
//pduCount = newFile.Open(currFile, arrayIndex, totalPdusRecorded);
System.out.println ("file " + filename + " loaded. ");
}
catch (Exception open_exception)
{
System.out.println("Error opening file " + filename);
System.out.println(open_exception);
}
bsbf = new BehaviorStreamBufferFile(file.getFile(), true);
fileInfo = bsbf.getInfo();
fileInfoMenuItem.setEnabled(true);
while((pdu=bsbf.getNextPdu()) != null)
{
pduBuffer.add(pdu);
//System.out.println("one more added, total now " + pduBuffer.size());
}
this.syncPduCount();
bsbf.cleanup();
String load_message = pduBuffer.size() + " PDUs loaded into memory.";
System.out.println (load_message);
//JOptionPane.showMessageDialog(PduPlayer.this, load_message);
}
/**
* Save file menu selection action. Called from the anonymous inner class action
* handler.
*/
public void saveFile()
{
BehaviorStreamBufferFile bsbf = new BehaviorStreamBufferFile(filename, fileInfo, false);
bsbf.setInfo(fileInfo);
fileInfoMenuItem.setEnabled(true);
Enumeration enum = pduBuffer.elements();
//int idx = 0;
while(enum.hasMoreElements())
{
ProtocolDataUnit pdu = (ProtocolDataUnit)enum.nextElement();
bsbf.sendPdu(pdu);
//System.out.println("saved " + idx);
//idx++;
}
bsbf.cleanup();
}
/**
* SaveAs menu operation. Open up a file dialog, then write out the contents of
* the pduBuffer to the file.
*/
public void saveAsFile()
{
BehaviorStreamBufferFile bsbf;
Enumeration enum = pduBuffer.elements();
String currFile, tempstr = "";
// Throw up a dialog to get the file name to save to.
msg = "Save File As";
file = new FileDialog(this, msg, state);
file.setDirectory("C:\\vrtp\\demo\\pduRecordings");
file.show();
if((currFile = file.getFile()) != null)
{
tempstr = currFile;
//fileName.setText(tempstr);
filename = tempstr;
}
bsbf = new BehaviorStreamBufferFile(filename, fileInfo, false);
bsbf.setInfo(fileInfo);
fileInfoMenuItem.setEnabled(true);
while(enum.hasMoreElements())
{
ProtocolDataUnit pdu = (ProtocolDataUnit)enum.nextElement();
bsbf.sendPdu(pdu);
}
bsbf.cleanup();
}
/**
* Action handler for the help menu, called from an anonymous inner class
* in the constructor. Launches the default web browser, with an argument
* that includes the help HTML file.
*/
public void helpMenu()
{
System.out.println(directory);
String BrowserNT1 = "cmd /k " + directory + "cd html";
String BrowserNT2 = "cmd /c " + directory + "guidds2.htm";
String Browser95 = "start " + directory + "html/guidds2.htm";
try
{
Process p1 = Runtime.getRuntime().exec(BrowserNT1);
Process p2 = Runtime.getRuntime().exec(BrowserNT2);
}
catch (IOException err1)
{
System.out.println("NT Operating System not found, trying 95...");
try
{
Process p = Runtime.getRuntime().exec(Browser95);
}
catch (IOException err2)
{
System.out.println(err2);
}
}
} // end helpMenu
/**
* Stop button hit. This calls code to perform the click on the
* stop button. A thread doing some operation, such as playing
* or rewinding, should call this method after finishing its
* task, just before exiting. It selects the stop button, and
* de-selects the current button.
*/
public void performStopButtonHit()
{
stopButton.doClick();
}
/**
* Rewind button hit. Checks the state and toggles intelligently.
* The rewind operation actually replays the PDUs in reverse order,
* from the current position. So if we're at PDU 42 currently, IN
* THE PDU LIST IN MEMORY, the pdus would be replayed back as 42, 41,
* 40, etc.
* * This has to launch a new thread (we can't process the lengthy rewind * action inside the action handler; that would stop the GUI.) */ public void rewindButtonHit() { Thread aThread; System.out.println("****In rewind button handler"); rewindObject = new Rewind(this, // us multicastAddress, // IP address to send to portNo, // port number to send to timeToLive); // ttl for mcast aThread = new Thread(rewindObject); aThread.start(); } /** * Handles a play button hit. Replays the pdus in memory, possibly * augmented by pdus from the file. */ public void playButtonHit() { Thread aThread; playObject = new Play(this, // us multicastAddress, // IP address to send to portNo, // port number to send to timeToLive); // ttl for mcast aThread = new Thread(playObject); aThread.start(); } /** * Automatic looping of the play button. This goes to the end * of the play, then loops back to the start of the in-memory * pdus. */ public void autoButtonHit() { Thread aThread; autoObject = new Play(this, // us multicastAddress, // IP address to send to portNo, // port number to send to timeToLive); // ttl for mcast autoObject.looping = true; aThread = new Thread(autoObject); aThread.start(); } // The fast forward button was hit. Play the pdus. public void ffwdButtonHit() { Thread aThread; ffwdObject = new FFwd(this, // us multicastAddress, // IP address to send to portNo, // port number to send to timeToLive); // ttl for mcast aThread = new Thread(ffwdObject); aThread.start(); } /** * The record button was hit; launch a thread to save the data to a * buffer. */ public void recordButtonHit() { Thread recordThread = null; recordObject = new Record(this, multicastAddress, portNo); recordThread = new Thread(recordObject); recordThread.setPriority(Thread.MIN_PRIORITY); System.out.println("starting record thread"); recordThread.start(); System.out.println("Exiting recordButtonHit"); } /** * Opens a dialog box with various properites from the prepend * data in the file displayed, for editing. */ public void runPropertiesDialog() { if(fileInfo == null) return; PropertiesDialog dialog = new PropertiesDialog(this, fileInfo); dialog.setVisible(true); if(dialog.getResult() == PropertiesDialog.OK) { String atVal = dialog.toString(); System.out.println("Got info from dialog of " + atVal); fileInfo = new BehaviorStreamBufferInfo(atVal); } } /** * Entry point for program. Lots of options ripped out here. In fact, all * options ripped out. Then the location salted, and no two stones left on * top of each other. */ public static void main(String args[]) { JFrame p = new PduPlayer(); p.setVisible(true); } }