This is the main method. What do ypu mean by Constructor?
Theodoros
/*
* Remote.java
*
* Copyright (c) 1996-1998 Brendon Wilson. All Rights Reserved.
*
* Brendon Wilson grants you ("Licensee") a non-exclusive, royalty free,
* license to use, modify and redistribute this software in source and binary
* code form, provided that i) this copyright notice and license appear on all
* copies of the software; and ii) Licensee does not utilize the software in a
* manner which is disparaging to Brendon Wilson.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
* IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
* NON-INFRINGEMENT, ARE HEREBY EXCLUDED. BRENDON WILSON SHALL NOT BE
* LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
* OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL BRENDON
* WILSON BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
* INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
* CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
* OR INABILITY TO USE SOFTWARE, EVEN IF BRENDON WILSON HAS BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* This software is not designed or intended for use in on-line control of
* aircraft, air traffic, aircraft navigation or aircraft communications; or in
* the design, construction, operation or maintenance of any nuclear
* facility. Licensee represents and warrants that it will not use or
* redistribute the Software for such purposes.
*/
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.*;
//import com.sun.j3d.utils.behaviors.mouse.*;
/**
* The main REMOTE application window.
*
* @author Brendon Wilson
* @version alpha
*/
public class Remote extends JFrame implements Observer, Runnable
{
// Progress frame variables.
public static int INITIAL_WIDTH = 400;
public static int INITIAL_HEIGHT = 200;
public static int totalPanels = 11;
public static int currentProgressValue = 0;
public static JLabel progressLabel = null;
public static JProgressBar progressBar = null;
// The core components required for the Simulation.
protected SimulationEngine theSimulationEngine;
protected Robot theRobot;
// The language and configuration resource Hashtables.
protected Hashtable rsrcTable = new Hashtable();
protected Hashtable cfgTable= new Hashtable();
// The application toolbar.
protected JToolBar toolbar;
// The 3D rendering canvas, and the 3D scene.
protected Canvas3D theViewport;
protected SimpleUniverse theUniverse;
protected BranchGroup theScene;
// Temporary holders for toggle buttons. Remove in 1.2 FCS.
protected JToggleButton zoomButton, translateButton, rotateButton;
// The Behaviors for controlling the 3D display.
protected MouseZoom zoom;
protected MouseTranslate translate;
protected MouseRotate rotate;
// The Cursors corresponding to the Behaviours..
protected Cursor zoomCursor;
protected Cursor translateCursor;
protected Cursor rotateCursor;
// The program editor component, and its popup menu.
protected JTextArea source;
// The Simulation Variables panel.
protected JPanel labelPanel= new JPanel();
// The frame used to display help information.
protected HelpFrame helpFrame;
// The directory and name of the current program.
protected String remoteFileName;
protected String remoteFileDir;
// Describe the state of the current program.
protected boolean alreadySaved = false;
protected boolean sourceChanged= false;
// Flag to indicate a request to stop the Thread.
protected boolean requestStop = false;
// The application Thread.
protected Thread remoteThread= new Thread(this);
// The default configuration strings.
String[][] config = {{"robotparser", "DefaultRobotParser"},
{"commandparser", "DefaultCommandParser"},
{"rbt", "config.rbt"}
};
// The default language strings.
String[][] resources = {{"remote.title", "REMOTE Robot Simulator - "},
{"remote.untitled", "Untitled"},
{"progress.config", "Loading Configuration..."},
{"progress.robot", "Loading Robot Model..."},
{"progress.commandparser", "Loading Simulation Language Parser..."},
{"progress.gui", "Initializing User Interface..."},
{"menus.file", "File"},
{"menus.file.new", "New"},
{"menus.file.new.shortcut", "N"},
{"menus.file.open", "Open..."},
{"menus.file.open.shortcut", "O"},
{"menus.file.save", "Save"},
{"menus.file.save.shortcut", "S"},
{"menus.file.saveas", "Save As..."},
{"menus.file.saveacopyas", "Save A Copy As..."},
{"menus.file.revert", "Revert"},
{"menus.file.quit", "Quit"},
{"menus.file.quit.shortcut", "Q"},
{"menus.edit", "Edit"},
{"menus.edit.cut", "Cut"},
{"menus.edit.cut.shortcut", "X"},
{"menus.edit.copy", "Copy"},
{"menus.edit.copy.shortcut", "C"},
{"menus.edit.paste", "Paste"},
{"menus.edit.paste.shortcut", "V"},
{"menus.edit.clear", "Clear"},
{"menus.edit.selectall", "Select All"},
{"menus.edit.selectall.shortcut", "A"},
{"menus.view", "View"},
{"menus.view.zoom", "Zoom Tool"},
{"menus.view.translate", "Translate Tool"},
{"menus.view.rotate", "Rotate Tool"},
{"menus.simulation", "Simulation"},
{"menus.simulation.start", "Start Simulation"},
{"menus.simulation.step", "Step Simulation"},
{"menus.simulation.stop", "Stop Simulation"},
{"menus.simulation.home", "Home Robot"},
{"menus.options", "Options"},
{"menus.options.setrobot", "Set Robot..."},
{"menus.options.setlanguage", "Set Command Language..."},
{"menus.options.setrobotparser", "Set Configuration Language..."},
{"menus.options.saveconfig", "Save Configuration"},
{"menus.help", "Help"},
{"menus.help.using", "Using Help..."},
{"menus.help.contents", "Help Contents..."},
{"menus.help.contents.shortcut", "H"},
{"menus.help.about", "About REMOTE..."},
{"dialogs.openfile", "Open File"},
{"dialogs.savefile", "Save File"},
{"dialogs.savefileas", "Save File As"},
{"dialogs.overwritefile", "Overwrite File"},
{"dialogs.error", "Error"},
{"dialogs.revert", "Revert To Saved"},
{"dialogs.messages.savefile", "The current file has not been\nsaved. Save file now?"},
{"dialogs.messages.overwritefile", "File already exists. \n Overwrite it?"},
{"dialogs.messages.revertfile", "Revert to previously saved \nversion of simulation?"},
{"errors.class", "File is not a class \n file or a valid parser."},
{"labels.editor", "Program Editor"},
{"labels.viewport", "Simulation Viewport"},
{"labels.variables", "Simulation Variables"},
{"toolbars.new", "new.gif"},
{"toolbars.open", "open.gif"},
{"toolbars.save", "save.gif"},
{"toolbars.cut", "cut.gif"},
{"toolbars.copy", "copy.gif"},
{"toolbars.paste", "paste.gif"},
{"toolbars.zoom", "zoom.gif"},
{"toolbars.translate", "translate.gif"},
{"toolbars.rotate", "rotate.gif"},
{"toolbars.start", "start.gif"},
{"toolbars.step", "step.gif"},
{"toolbars.stop", "stop.gif"},
{"toolbars.home", "home.gif"},
{"toolbars.help", "help.gif"},
{"toolbars.new.tooltip", "Create a new file"},
{"toolbars.open.tooltip", "Open an existing file"},
{"toolbars.save.tooltip", "Save the current file"},
{"toolbars.cut.tooltip", "Cut text from editor"},
{"toolbars.copy.tooltip", "Copy text from editor"},
{"toolbars.paste.tooltip", "Paste text to editor"},
{"toolbars.zoom.tooltip", "Tool to zoom in or out of the scene"},
{"toolbars.translate.tooltip", "Tool to translate the scene"},
{"toolbars.rotate.tooltip", "Tool to rotate the scene"},
{"toolbars.start.tooltip", "Start the simulation"},
{"toolbars.step.tooltip", "Step the simulation"},
{"toolbars.stop.tooltip", "Stop the simulation"},
{"toolbars.home.tooltip", "Return robot to the home position"},
{"toolbars.help.tooltip", "View help contents"},
{"cursors.zoom", "zoom.gif"},
{"cursors.translate", "translate.gif"},
{"cursors.rotate", "rotate.gif"}
};
/**
* Start the application; if two command-line arguments are given,
* these are assumed to be the two-letter language and country codes,
* which are used to set a new default Locale for the application.
*
* @param args the command-line arguments.
*/
public static void main(String args[])
{
String defaultLookAndFeel = UIManager.getSystemLookAndFeelClassName();
if (defaultLookAndFeel != null)
{
try
{
UIManager.setLookAndFeel(defaultLookAndFeel);
}
catch (Exception e)
{
// Catches ClassNotFoundException, UnsupportLookAndFeel,
// IllegalAccessException, InstantiationException
// Use the default Java L&F.
}
}
if (args.length == 2)
{
java.util.Locale.setDefault(new java.util.Locale(args[0], args[1]));
}
JFrame frame = new JFrame("REMOTE");
JPanel progressPanel = new JPanel()
{
public Insets getInsets()
{
return new Insets(40,30,20,30);
}
};
progressPanel.setLayout(new BoxLayout(progressPanel, BoxLayout.Y_AXIS));
frame.getContentPane().add(progressPanel, BorderLayout.CENTER);
Dimension d = new Dimension(400, 20);
Remote.progressLabel = new JLabel("Loading, please wait...");
Remote.progressLabel.setAlignmentX(CENTER_ALIGNMENT);
Remote.progressLabel.setMaximumSize(d);
Remote.progressLabel.setPreferredSize(d);
progressPanel.add(progressLabel);
progressPanel.add(Box.createRigidArea(new Dimension(1,20)));
Remote.progressBar = new JProgressBar();
Remote.progressLabel.setLabelFor(progressBar);
Remote.progressBar.setAlignmentX(CENTER_ALIGNMENT);
Remote.progressBar.setMinimum(0);
Remote.progressBar.setMaximum(Remote.totalPanels);
Remote.progressBar.setValue(0);
progressPanel.add(Remote.progressBar);
// Show the frame.
frame.setIconImage((new ImageIcon("images" + System.getProperty("file.separator") + "remote.gif")).getImage());
frame.setSize(INITIAL_WIDTH, INITIAL_HEIGHT);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(screenSize.width/2 - INITIAL_WIDTH/2,
screenSize.height/2 - INITIAL_HEIGHT/2);
frame.show();
frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
Remote r = new Remote();
r.show();
frame.setVisible(false);
frame.dispose();
}
/**
* Public constructor, initiates the window, menus, popup menus, and the
* initiates the internal simulation engine.
*
* @param title the Frame title.
*/
public Remote()
{
super("");
// Remote'll take care of all windoe-closing duties.
this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setIconImage((new ImageIcon("images" + System.getProperty("file.separator") + "remote.gif")).getImage());
RemoteObservable o = new RemoteObservable();
fillResources();
progressBar.setValue(++currentProgressValue);
this.setTitle((String) rsrcTable.get("remote.title") + (String) rsrcTable.get("remote.untitled"));
o.addObserver(this);
theSimulationEngine = new SimulationEngine();
try
{
progressLabel.setText((String) rsrcTable.get("progress.configuration"));
Reader reader = new FileReader(new File(System.getProperty("user.dir") + System.getProperty("file.separator") + "rbt", (String) cfgTable.get("rbt")));
progressBar.setValue(++currentProgressValue);
progressLabel.setText((String) rsrcTable.get("progress.robot"));
theRobot = Robot.getInstance();
theRobot.loadRobotModel((String) cfgTable.get("robotparser"), reader);
theRobot.setObservable(o);
progressBar.setValue(++currentProgressValue);
progressBar.setValue(++currentProgressValue);
}
catch (FileNotFoundException fnfe)
{
displayMessage((String) rsrcTable.get("dialogs.error"), fnfe.getMessage());
System.exit(1);
}
catch (RobotParserException see)
{
displayMessage((String) rsrcTable.get("dialogs.error"), see.getMessage());
System.exit(1);
}
try
{
progressLabel.setText((String) rsrcTable.get("progress.commandparser"));
CommandParser c = CommandParser.loadParser((String) cfgTable.get("commandparser"));
c.setNameTable(theRobot.getJointVariables().getNameTable());
theSimulationEngine.setCommandParser(c);
progressBar.setValue(++currentProgressValue);
}
catch (CommandParserException cpe)
{
displayMessage((String) rsrcTable.get("dialogs.error"), cpe.getMessage());
}
progressLabel.setText((String) rsrcTable.get("progress.gui"));
this.setMenuBar(createMenuBar());
// Set up the layout constraints.
GridBagConstraints c = new GridBagConstraints();
GridBagLayout l = new GridBagLayout();
c.gridwidth = 1;
c.gridheight = 1;
c.ipadx = 2;
c.ipady = 2;
c.anchor = c.WEST;
c.fill = c.BOTH;
c.insets = new Insets(2, 2, 2, 2);
c.weightx = 1;
c.weighty = 1;
c.gridx = 0;
c.gridy = 0;
// Configure the 3D rendering canvas.
theViewport = new RemoteCanvas3D();
theViewport.setSize(400, 300);
// Add the scenegraph to the universe.
theScene = new BranchGroup();
theScene.setCapability(BranchGroup.ALLOW_DETACH);
theScene.addChild(createScene());
theUniverse = new SimpleUniverse(theViewport);
theUniverse.getViewingPlatform().setNominalViewingTransform();
theUniverse.addBranchGraph(theScene);
progressBar.setValue(++currentProgressValue);
// Create the Simulation Viewport panel.
JPanel viewPanel = new JPanel();
viewPanel.setLayout(l);
l.setConstraints(theViewport, c);
viewPanel.setBorder(new TitledBorder((String) rsrcTable.get("labels.viewport")));
viewPanel.add(theViewport);
progressBar.setValue(++currentProgressValue);
// Create the Simulation Variables status panel.
JPanel statusPanel= new JPanel();
statusPanel.setLayout(l);
l.setConstraints(labelPanel = createStatus(), c);
statusPanel.add(labelPanel);
statusPanel.setBorder(new TitledBorder((String) rsrcTable.get("labels.variables")));
progressBar.setValue(++currentProgressValue);
// Create the Program Editor panel.
source = new JTextArea("", 20, 30);
source.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
JScrollPane scroller = new JScrollPane();
JViewport port = scroller.getViewport();
port.add(source);
port.setBackingStoreEnabled(true);
source.getDocument().addDocumentListener(new AppDocHandler());
JPanel textAreaPanel = new JPanel();
textAreaPanel.setBorder(new TitledBorder((String) rsrcTable.get("labels.editor")));
textAreaPanel.setLayout(new BorderLayout());
textAreaPanel.add("Center", scroller);
progressBar.setValue(++currentProgressValue);
// Create the JSplitPane's to hold the other Panel's.
JSplitPane splitPane1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, false, viewPanel, statusPanel);
JSplitPane splitPane2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, false, splitPane1, textAreaPanel);
JPanel holderPanel = new JPanel();
holderPanel.setLayout(l);
l.setConstraints(splitPane2, c);
holderPanel.add(splitPane2);
progressBar.setValue(++currentProgressValue);
// Put it all together, adding the toolbar.
JPanel appPanel = new JPanel();
appPanel.setLayout(new BorderLayout());
appPanel.add(this.toolbar=createJToolBar(), BorderLayout.NORTH);
appPanel.add(holderPanel, BorderLayout.CENTER);
this.getContentPane().add(appPanel);
progressBar.setValue(++currentProgressValue);
// Create the behaviour Cursors.
Toolkit theToolkit = Toolkit.getDefaultToolkit();
String dir = "images" + System.getProperty("file.separator");
Image img = new ImageIcon(dir + (String) rsrcTable.get("cursors.zoom")).getImage();
Point hotspot = new Point(0,0);
zoomCursor = theToolkit.createCustomCursor(img, hotspot, (String) rsrcTable.get("toolbars.zoom.tooltip"));
img = new ImageIcon(dir + (String) rsrcTable.get("cursors.translate")).getImage();
translateCursor = theToolkit.createCustomCursor(img, hotspot, (String) rsrcTable.get("toolbars.translate.tooltip"));
img = new ImageIcon(dir + (String) rsrcTable.get("cursors.rotate")).getImage();
rotateCursor = theToolkit.createCustomCursor(img, hotspot, (String) rsrcTable.get("toolbars.rotate.tooltip"));
// Set the location and size of the application.
Dimension theDimension = theToolkit.getScreenSize();
this.setSize(theDimension.width, theDimension.height);
int x = theDimension.width / 2 - this.getSize().width / 2;
int y = theDimension.height / 2 - this.getSize().height / 2;
this.setLocation(x, y);
this.addWindowListener(new AppWinHandler());
try
{
String location = "file:" + System.getProperty("user.dir") + System.getProperty("file.separator")
+ "help" + System.getProperty("file.separator")
+ "index.html";
helpFrame = new HelpFrame("Help", location);
}
catch (MalformedURLException mfue) {}
catch (IOException ioe) {}
}
/**
* Creates the BranchGroup.
*
* @return the 3D representation of the Robot.
*/
public BranchGroup createScene()
{
// Create a BranchGroup, and set capability.
BranchGroup branch = new BranchGroup();
branch.setCapability(BranchGroup.ALLOW_DETACH);
branch.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
branch.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
// Create a TransformGroup for the scene.
TransformGroup objScale = new TransformGroup();
Transform3D t3d = new Transform3D();
t3d.setScale(theRobot.getZoom());
objScale.setTransform(t3d);
// Create the bounding leaf node.
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 1000.0);
BoundingLeaf boundingLeaf = new BoundingLeaf(bounds);
objScale.addChild(boundingLeaf);
// Set up the background color.
Background bg = new Background( 0.1f, 0.4f, 0.7f );
bg.setApplicationBounds(bounds);
objScale.addChild(bg);
// Create the ambient light.
DirectionalLight dl = new DirectionalLight( new Color3f( 1.0f, 1.0f, 1.0f ),
new Vector3f( 0.0f, 0.0f, -1.0f ) );
dl.setInfluencingBounds(bounds);
objScale.addChild(dl);
Vector3f direction = new Vector3f( -4.0f, -6.0f, -4.0f );
direction.normalize();
dl = new DirectionalLight( new Color3f( 1.0f, 1.0f, 1.0f ),
direction );
dl.setInfluencingBounds(bounds);
objScale.addChild(dl);
// Create the TransformGroup node.
TransformGroup transformGroup = new TransformGroup();
Matrix3d m = new Matrix3d();
Matrix3d m1 = new Matrix3d();
switch (theRobot.getUpAxis())
{
case Robot.X_UP:
{
m1.rotX(theRobot.getRotation() * Math.PI / 180.0);
m.rotY(-Math.PI / 2.0);
m.mul(m1);
break;
}
case Robot.Y_UP:
{
m.rotY(theRobot.getRotation() * Math.PI / 180.0);
break;
}
case Robot.Z_UP:
{
m1.rotZ(theRobot.getRotation() * Math.PI / 180.0);
m.rotX(-Math.PI / 2.0);
m.mul(m1);
break;
}
}
t3d = new Transform3D();
t3d.setRotation(m);
transformGroup.setTransform(t3d);
transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
transformGroup.addChild(theRobot.getModels());
objScale.addChild(transformGroup);
// Create the zoom behavior node.
zoom = new MouseZoom();
zoom.setTransformGroup(transformGroup);
transformGroup.addChild(zoom);
zoom.setSchedulingBounds(bounds);
zoom.setEnable(false);
// Create the translate behavior node.
translate = new MouseTranslate();
translate.setTransformGroup(transformGroup);
transformGroup.addChild(translate);
translate.setSchedulingBounds(bounds);
translate.setEnable(false);
// Create the rotate behavior node.
rotate = new MouseRotate();
rotate.setTransformGroup(transformGroup);
transformGroup.addChild(rotate);
rotate.setSchedulingBounds(bounds);
rotate.setEnable(false);
// Let Java 3D perform optimizations on this scene graph.
branch.addChild(objScale);
branch.compile();
return branch;
}
/**
* Create the Simulation Variables JPanel.
*
* @return the completed Simulation Variable JPanel.
*/
public JPanel createStatus()
{
GridBagConstraints c = new GridBagConstraints();
GridBagLayout l = new GridBagLayout();
JPanel jp = new JPanel();
c.gridwidth = 1;
c.gridheight = 1;
c.ipadx = 2;
c.ipady = 2;
c.anchor = c.WEST;
c.fill = c.HORIZONTAL;
c.insets = new Insets(2, 2, 2, 2);
c.weightx = 0.25;
c.weighty = 1;
jp.setLayout(l);
int count = 0;
for (int i = 1; i <= theRobot.getJointVariables().countJoints(); i++)
{
Joint currentJoint = theRobot.getJointVariables().getJoint(i);
for (int j = 1; j <= currentJoint.countDegrees(); j++)
{
Degree currentDegree = currentJoint.getDegree(j);
if (currentDegree.getType() != Degree.TYPE_INANIMATE)
{
JLabel currentLabel = new JLabel(currentDegree.getName());
c.gridx = 0;
c.gridy = count;
l.setConstraints(currentLabel, c);
jp.add(currentLabel);
count++;
}
}
}
c.anchor = c.EAST;
c.weightx = 0.75;
count = 0;
for (int i = 1; i <= theRobot.getJointVariables().countJoints(); i++)
{
Joint currentJoint = theRobot.getJointVariables().getJoint(i);
for (int j = 1; j <= currentJoint.countDegrees(); j++)
{
Degree currentDegree = currentJoint.getDegree(j);
if (currentDegree.getType() != Degree.TYPE_INANIMATE)
{
JLabel currentLabel = new JLabel((new Double(currentDegree.getVariable())).toString());
c.gridx = 1;
c.gridy = count;
l.setConstraints(currentLabel, c);
jp.add(currentLabel);
count++;
}
}
}
return jp;
}
/**
* Creates a MenuItem. Should be updated to use MenuItem once Swing is stable.
*
* @param s the resource string to use to retrieve the language-specific label.
* @param sc indicates whether or not to create a MenuShortcut for this MenuItem.
* @param a the ActionListener to handle events.
* @return the completed MenuItem.
*/
public MenuItem createMenuItem(String s, boolean sc, ActionListener a)
{
MenuItem mi;
MenuShortcut ms;
if (sc)
{
ms = new MenuShortcut((int) ((String) rsrcTable.get(s +".shortcut")).charAt(0));
mi = new MenuItem((String) rsrcTable.get(s), ms);
}
else
{
mi = new MenuItem((String) rsrcTable.get(s));
}
mi.addActionListener(a);
return mi;
}
/**
* Creates and returns the MenuBar for the application. Update to Swing once stable,
* and solution to Canvas3D heavy-weight problem.
*
* @return the completed application MenuBar object.
*/
public MenuBar createMenuBar()
{
MenuBar mb = new MenuBar();
Menu m;
// The File menu.
m = new Menu((String) rsrcTable.get("menus.file"));
m.add(createMenuItem("menus.file.new", true, new AppFileNewHandler()));
m.add(createMenuItem("menus.file.open", true, new AppFileOpenHandler()));
m.addSeparator();
m.add(createMenuItem("menus.file.save", true, new AppFileSaveHandler()));
m.add(createMenuItem("menus.file.saveas", false, new AppFileSaveAsHandler()));
m.add(createMenuItem("menus.file.saveacopyas", false, new AppFileSaveACopyAsHandler()));
m.add(createMenuItem("menus.file.revert", false, new AppFileRevertHandler()));
m.addSeparator();
m.add(createMenuItem("menus.file.quit", true, new AppFileQuitHandler()));
mb.add(m);
// The Edit menu.
m = new Menu((String) rsrcTable.get("menus.edit"));
m.add(createMenuItem("menus.edit.cut", true, new AppEditCutHandler()));
m.add(createMenuItem("menus.edit.copy", true, new AppEditCopyHandler()));
m.add(createMenuItem("menus.edit.paste", true, new AppEditPasteHandler()));
m.addSeparator();
m.add(createMenuItem("menus.edit.clear", false, new AppEditClearHandler()));
m.add(createMenuItem("menus.edit.selectall", true, new AppEditSelectAllHandler()));
mb.add(m);
// The View menu.
m = new Menu((String) rsrcTable.get("menus.view"));
m.add(createMenuItem("menus.view.zoom", false, new AppViewZoomHandler()));
m.add(createMenuItem("menus.view.translate", false, new AppViewTranslateHandler()));
m.add(createMenuItem("menus.view.rotate", false, new AppViewRotateHandler()));
mb.add(m);
// The Simulation menu.
m = new Menu((String) rsrcTable.get("menus.simulation"));
m.add(createMenuItem("menus.simulation.start", false, new AppSimStartHandler()));
m.add(createMenuItem("menus.simulation.step", false, new AppSimStepHandler()));
m.add(createMenuItem("menus.simulation.stop", false, new AppSimStopHandler()));
m.add(createMenuItem("menus.simulation.home", false, new AppSimHomeHandler()));
mb.add(m);
// The Options menu.
m = new Menu((String) rsrcTable.get("menus.options"));
m.add(createMenuItem("menus.options.setrobot", false, new AppOptionsRobotHandler()));
m.add(createMenuItem("menus.options.setlanguage", false, new AppOptionsLanguageHandler()));
m.add(createMenuItem("menus.options.setrobotparser", false, new AppOptionsParserHandler()));
m.addSeparator();
m.add(createMenuItem("menus.options.saveconfig", false, new AppOptionsSaveConfigHandler()));
mb.add(m);
// The Help menu.
m = new Menu((String) rsrcTable.get("menus.help"));
//m.add(createMenuItem("menus.help.using", false, new AppHelpUsingHandler()));
m.add(createMenuItem("menus.help.contents", true, new AppHelpContentsHandler()));
m.add(createMenuItem("menus.help.about", false, new AppHelpAboutHandler()));
mb.setHelpMenu(m);
return mb;
}
/**
* Creates a JButton, using the given resource string, and actioncommand string.
*
* @param s the resource String.
* @param a the ActionCommand String.
* @param e indicates if this JButton should be enabled.
* @param al the ActionListener to handle events.
* @return the completed JButton.
*/
public JButton createJButton(String s, String a, boolean e, ActionListener al)
{
JButton jb;
String dir = "images" + System.getProperty("file.separator");
jb = new JButton(new ImageIcon(dir + (String) rsrcTable.get(s)));
jb.setToolTipText((String) rsrcTable.get(s +".tooltip"));
jb.setMargin(new Insets(0,0,0,0));
jb.setActionCommand((String) rsrcTable.get(a));
jb.addActionListener(al);
jb.setEnabled(e);
return jb;
}
/**
* Creates a JToggleButton, using the given resource string, and actioncommand string.
*
* @param s the resource String.
* @param a the ActionCommand String.
* @param e indicates if this JToggleButton should be selected.
* @param al the ActionListener to handle events.
* @return the completed JButton.
*/
public JToggleButton createJToggleButton(String s, String a, boolean e, ActionListener al)
{
JToggleButton jtb;
String dir = "images" + System.getProperty("file.separator");
jtb = new JToggleButton(new ImageIcon(dir + (String) rsrcTable.get(s)));
jtb.setToolTipText((String) rsrcTable.get(s +".tooltip"));
jtb.setMargin(new Insets(0,0,0,0));
jtb.setActionCommand((String) rsrcTable.get(a));
jtb.addActionListener(al);
jtb.setSelected(e);
return jtb;
}
/**
* Creates the toolbar for the application.
*
* @return the completed toolbar.
*/
public JToolBar createJToolBar()
{
JToolBar jtb = new JToolBar();
jtb.setFloatable(false);
// File operations.
jtb.add(createJButton("toolbars.new", "menus.file.new", true, new AppFileNewHandler()));
jtb.add(createJButton("toolbars.open", "menus.file.open", true, new AppFileOpenHandler()));
jtb.add(createJButton("toolbars.save", "menus.file.save", true, new AppFileSaveHandler()));
jtb.addSeparator();
// Edit operations.
jtb.add(createJButton("toolbars.cut", "menus.edit.cut", true, new AppEditCutHandler()));
jtb.add(createJButton("toolbars.copy", "menus.edit.copy", true, new AppEditCopyHandler()));
jtb.add(createJButton("toolbars.paste", "menus.edit.paste", true, new AppEditPasteHandler()));
jtb.addSeparator();
// View operations.
ButtonGroup b = new ButtonGroup();
b.add(zoomButton = createJToggleButton("toolbars.zoom", "menus.view.zoom", false, new AppViewZoomHandler()));
b.add(translateButton = createJToggleButton("toolbars.translate", "menus.view.translate", false, new AppViewTranslateHandler()));
b.add(rotateButton = createJToggleButton("toolbars.rotate", "menus.view.rotate", false, new AppViewRotateHandler()));
jtb.add(zoomButton);
jtb.add(translateButton);
jtb.add(rotateButton);
jtb.addSeparator();
// Simulation operations.
jtb.add(createJButton("toolbars.home", "menus.simulation.home", true, new AppSimHomeHandler()));
jtb.add(createJButton("toolbars.stop", "menus.simulation.stop", false, new AppSimStopHandler()));
jtb.add(createJButton("toolbars.step", "menus.simulation.step", true, new AppSimStepHandler()));
jtb.add(createJButton("toolbars.start", "menus.simulation.start", true, new AppSimStartHandler()));
jtb.addSeparator();
// Help operations.
jtb.add(createJButton("toolbars.help", "menus.help.contents", true, new AppHelpContentsHandler()));
return jtb;
}
/**
* Fills up the resources using the hardcoded and soft-loaded resources.
*/
public void fillResources()
{
try
{
ResourceBundle bundle = ResourceBundle.getBundle("RemoteConfig");
rsrcTable = new Hashtable();
for (int i = 0; i < resources.length; i++)
{
String temp;
try
{
temp = bundle.getString(resources[i][0]);
}
catch (MissingResourceException mre)
{
System.err.println("Missing resource:" + resources[i][0]);
temp = resources[i][1];
}
rsrcTable.put(resources[i][0], temp);
}
}
catch (MissingResourceException mre)
{
System.err.println("RemoteFrame: Unable to find language resources.");
String tempName = "RemoteConfig.properties";
File theFile = new File(tempName);
if (!theFile.exists())
{
try
{
FileWriter writer = new FileWriter(theFile);
for (int i = 0; i < resources.length; i++)
{
rsrcTable.put(resources[i][0], resources[i][1]);
writer.write(resources[i][0]+"="+resources[i][1]+System.getProperty("line.separator"));
}
writer.close();
}
catch (IOException ie){}
}
}
try
{
ResourceBundle bundle = ResourceBundle.getBundle("Config");
cfgTable = new Hashtable();
for (int i = 0; i < config.length; i++)
{
String temp;
try
{
temp = bundle.getString(config[i][0]);
}
catch (MissingResourceException mre)
{
System.err.println("Missing resource:" + config[i][0]);
temp = config[i][1];
}
cfgTable.put(config[i][0], temp);
}
}
catch (MissingResourceException mre)
{
String tempName = "Config.properties";
File theFile = new File(tempName);
if (!theFile.exists())
{
try
{
FileWriter writer = new FileWriter(theFile);
for (int i = 0; i < config.length; i++)
{
cfgTable.put(config[i][0], config[i][1]);
writer.write(config[i][0]+"="+config[i][1]+System.getProperty("line.separator"));
}
writer.close();
}
catch (IOException ie){}
}
}
}
/**
* Starts the application thread.
*/
public void start()
{
if (!remoteThread.isAlive())
{
remoteThread = new Thread(this);
remoteThread.setPriority(Thread.NORM_PRIORITY);
requestStop = false;
remoteThread.start();
}
}
/**
* The application Thread run loop.
*/
public void run()
{
while (!theSimulationEngine.isComplete() && !requestStop)
{
remoteThread.yield();
}
enableUI();
}
/**
* Stops the remote thread. Note that this method is not meant to implement
* Runnable.stop(), due to its deprecation in JDK 1.2. Instead, it changes
* a boolean flag, which is used to exit the run(), allowing the Thread to
* terminate properly.
*/
public void stop()
{
requestStop = true;
}
/**
* Enables the application's toolbar items and MenuItems,
* which were disabled during simulation.
*/
public void enableUI()
{
this.getMenuBar().getHelpMenu().setEnabled(true);
this.getMenuBar().getMenu(0).setEnabled(true);
this.getMenuBar().getMenu(1).setEnabled(true);
this.getMenuBar().getMenu(4).setEnabled(true);
this.getMenuBar().getMenu(3).getItem(0).setEnabled(true);
this.getMenuBar().getMenu(3).getItem(1).setEnabled(true);
this.getMenuBar().getMenu(3).getItem(2).setEnabled(false);
this.getMenuBar().getMenu(3).getItem(3).setEnabled(true);
((JButton) this.toolbar.getComponent(0)).setEnabled(true);
((JButton) this.toolbar.getComponent(1)).setEnabled(true);
((JButton) this.toolbar.getComponent(2)).setEnabled(true);
((JButton) this.toolbar.getComponent(4)).setEnabled(true);
((JButton) this.toolbar.getComponent(5)).setEnabled(true);
((JButton) this.toolbar.getComponent(6)).setEnabled(true);
((JButton) this.toolbar.getComponent(12)).setEnabled(true);
((JButton) this.toolbar.getComponent(13)).setEnabled(false);
((JButton) this.toolbar.getComponent(14)).setEnabled(true);
((JButton) this.toolbar.getComponent(15)).setEnabled(true);
((JButton) this.toolbar.getComponent(17)).setEnabled(true);
}
/**
* Disables the application's toolbar items and MenuItems,
* to prevent input during simulation.
*/
public void disableUI()
{
this.getMenuBar().getHelpMenu().setEnabled(false);
this.getMenuBar().getMenu(0).setEnabled(false);
this.getMenuBar().getMenu(1).setEnabled(false);
this.getMenuBar().getMenu(4).setEnabled(false);
this.getMenuBar().getMenu(3).getItem(0).setEnabled(false);
this.getMenuBar().getMenu(3).getItem(1).setEnabled(false);
this.getMenuBar().getMenu(3).getItem(2).setEnabled(true);
this.getMenuBar().getMenu(3).getItem(3).setEnabled(false);
((JButton) this.toolbar.getComponent(0)).setEnabled(false);
((JButton) this.toolbar.getComponent(1)).setEnabled(false);
((JButton) this.toolbar.getComponent(2)).setEnabled(false);
((JButton) this.toolbar.getComponent(4)).setEnabled(false);
((JButton) this.toolbar.getComponent(5)).setEnabled(false);
((JButton) this.toolbar.getComponent(6)).setEnabled(false);
((JButton) this.toolbar.getComponent(12)).setEnabled(false);
((JButton) this.toolbar.getComponent(13)).setEnabled(true);
((JButton) this.toolbar.getComponent(14)).setEnabled(false);
((JButton) this.toolbar.getComponent(15)).setEnabled(false);
((JButton) this.toolbar.getComponent(17)).setEnabled(false);
}
/**
* Updates the joint variable output display.
*/
public void updateStatus()
{
Component theComponents[] = labelPanel.getComponents();
int offset = labelPanel.getComponentCount();
int count = 0;
if (labelPanel.getComponentCount() != 0)
{
for (int i = 1; i <= theRobot.getJointVariables().countJoints(); i++)
{
Joint currentJoint = theRobot.getJointVariables().getJoint(i);
for (int j = 1; j <= currentJoint.countDegrees(); j++)
{
Degree currentDegree = currentJoint.getDegree(j);
JLabel currentLabel = (JLabel) theComponents[count + offset/2];
if (currentDegree.getType() != Degree.TYPE_INANIMATE)
{
currentLabel.setText((new Double(currentDegree.getVariable())).toString());
count++;
}
}
}
}
}
/**
* Returns the root component.
*
* @return this instance, which is the root of all the GUI.
*/
public JFrame getRootComponent()
{
return this;
}
/**
* Displays a message from the application.
*
* @param title the title for the information Dialog.
* @param message the message for the information Dialog.
*/
protected void displayMessage(String title, String message)
{
JOptionPane.showMessageDialog(null, message, title, JOptionPane.ERROR_MESSAGE);
}
/**
* Update the object's representation of the robot whenever the model
* is changed elsewhere by either the parsers or the simulation engine.
*
* @param o Observable object which is attempting to update this object.
* @param arg the argument Object for the update.
*/
public void update(Observable o, Object arg)
{
if (arg instanceof JointVariables)
{
try
{
updateStatus();
}
catch (ArrayIndexOutOfBoundsException aioobe) {}
}
}
/**
* Inner class to handle the File->New menu item.
*/
public class AppFileNewHandler implements ActionListener
{
/**
* Handles the File->New event.
*
* @param e the ActionEvent fired by the File->New menu item.
*/
public void actionPerformed(ActionEvent e)
{
if (sourceChanged)
{
String title = (String) rsrcTable.get("dialogs.savefile");
String msg = (String) rsrcTable.get("dialogs.messages.savefile");
int result = JOptionPane.showConfirmDialog(getRootComponent(), msg, title, JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION)
{
AppFileSaveHandler save = new AppFileSaveHandler();
save.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, (String) rsrcTable.get("menus.file.save")));
if (alreadySaved)
{
AppFileNewHandler newer = new AppFileNewHandler();
newer.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, (String) rsrcTable.get("menus.file.new")));
}
}
else if (result == JOptionPane.NO_OPTION)
{
theRobot.home();
source.setText("");
source.setCaretPosition(0);
sourceChanged = false;
source.getDocument().addDocumentListener(new AppDocHandler());
alreadySaved = false;
getRootComponent().setTitle((String) rsrcTable.get("remote.title") + (String) rsrcTable.get("remote.untitled"));
}
}
else
{
theRobot.home();
source.setText("");
source.setCaretPosition(0);
sourceChanged = false;
alreadySaved = false;
getRootComponent().setTitle((String) rsrcTable.get("remote.title") + (String) rsrcTable.get("remote.untitled"));
}
}
}
/**
* Inner class to handle the File->Open menu item.
*/
public class AppFileOpenHandler implements ActionListener
{
/**
* Handles the File->Open event.
*
* @param e the ActionEvent fired by the File->Open menu item.
*/
public void actionPerformed(ActionEvent e)
{
FileDialog remoteFileDialog;
if (sourceChanged)
{
String title = (String) rsrcTable.get("dialogs.savefile");
String msg = (String) rsrcTable.get("dialogs.messages.savefile");
int result = JOptionPane.showConfirmDialog(getRootComponent(), msg, title, JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION)
{
AppFileSaveHandler save = new AppFileSaveHandler();
save.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, (String) rsrcTable.get("menus.file.save")));
if (alreadySaved)
{
AppFileOpenHandler open = new AppFileOpenHandler();
open.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, (String) rsrcTable.get("menus.file.open")));
}
}
else if (result == JOptionPane.NO_OPTION)
{
remoteFileDialog = new FileDialog(getRootComponent(), (String) rsrcTable.get("dialogs.openfile"), FileDialog.LOAD);
remoteFileDialog.show();
remoteFileDialog.setVisible(false);
remoteFileName = remoteFileDialog.getFile();
remoteFileDir = remoteFileDialog.getDirectory();
remoteFileDialog.dispose();
if (remoteFileName != null)
{
try
{
File theFile = new File(remoteFileDir, remoteFileName);
LineNumberReader theFileReader = new LineNumberReader(new FileReader(theFile));
String program = new String();
while (theFileReader.ready())
{
program += theFileReader.readLine() + System.getProperty("line.separator");
}
source.setText(program);
}
catch (FileNotFoundException fe)
{
displayMessage((String) rsrcTable.get("dialogs.error"), fe.getMessage());
}
catch (IOException ie)
{
displayMessage((String) rsrcTable.get("dialogs.error"), ie.getMessage());
}
getRootComponent().setTitle((String) rsrcTable.get("remote.title") + remoteFileName);
sourceChanged = false;
source.setCaretPosition(0);
source.getDocument().addDocumentListener(new AppDocHandler());
theRobot.home();
alreadySaved = true;
}
}
}
else
{
remoteFileDialog = new FileDialog(getRootComponent(), (String) rsrcTable.get("dialogs.openfile"), FileDialog.LOAD);
remoteFileDialog.show();
remoteFileDialog.setVisible(false);
remoteFileName = remoteFileDialog.getFile();
remoteFileDir = remoteFileDialog.getDirectory();
remoteFileDialog.dispose();
if (remoteFileName != null)
{
try
{
File theFile = new File(remoteFileDir, remoteFileName);LineNumberReader theFileReader = new LineNumberReader(new FileReader(theFile));
String program = new String();
while (theFileReader.ready())
{
program += theFileReader.readLine() + System.getProperty("line.separator");
}
source.setText(program);
}
catch (FileNotFoundException fe)
{
displayMessage((String) rsrcTable.get("dialogs.error"), fe.getMessage());
}
catch (IOException ie)
{
displayMessage((String) rsrcTable.get("dialogs.error"), ie.getMessage());
}
getRootComponent().setTitle((String) rsrcTable.get("remote.title") + remoteFileName);
sourceChanged = false;
source.setCaretPosition(0);
theRobot.home();
alreadySaved = true;
}
}
}
}
/**
* Inner class to handle the File->Save menu item.
*/
public class AppFileSaveHandler implements ActionListener
{
/**
* Handles the File->Save event.
*
* @param e the ActionEvent fired by the File->Save menu item.
*/
public void actionPerformed(ActionEvent e)
{
if (alreadySaved)
{
if (sourceChanged)
{
try
{
File theFile = new File(remoteFileDir, remoteFileName);
FileWriter writer = new FileWriter(theFile);
writer.write(source.getText());
writer.close();
}
catch (IOException ie)
{
displayMessage((String) rsrcTable.get("dialogs.error"), ie.getMessage());
}
getRootComponent().setTitle((String) rsrcTable.get("remote.title") + remoteFileName);
sourceChanged = false;
source.getDocument().addDocumentListener(new AppDocHandler());
alreadySaved = true;
}
}
else
{
if (sourceChanged)
{
AppFileSaveAsHandler a = new AppFileSaveAsHandler();
a.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, (String) rsrcTable.get("menus.file.saveas")));
}
}
}
}
/**
* Inner class to handle the File->Save As... menu item.
*/
public class AppFileSaveAsHandler implements ActionListener
{
/**
* Handles the File->Save As... event.
*
* @param e the ActionEvent fired by the File->Save As... menu item.
*/
public void actionPerformed(ActionEvent e)
{
FileDialog remoteFileDialog;
remoteFileDialog = new FileDialog(getRootComponent(), (String) rsrcTable.get("dialogs.savefileas"), FileDialog.SAVE);
remoteFileDialog.show();
remoteFileDialog.setVisible(false);
remoteFileName = remoteFileDialog.getFile();
remoteFileDir = remoteFileDialog.getDirectory();
remoteFileDialog.dispose();
if (remoteFileName != null)
{
File theFile = new File(remoteFileDir, remoteFileName);
if (!theFile.exists())
{
try
{
FileWriter writer = new FileWriter(theFile);
writer.write(source.getText());
writer.close();
}
catch (IOException ie)
{
displayMessage((String) rsrcTable.get("dialogs.error"), ie.getMessage());
}
getRootComponent().setTitle((String) rsrcTable.get("remote.title") + remoteFileName);
sourceChanged = false;
alreadySaved = true;
}
else
{
String title = (String) rsrcTable.get("dialogs.overwritefile");
String msg = (String) rsrcTable.get("dialogs.messages.overwritefile");
int result = JOptionPane.showConfirmDialog(getRootComponent(), msg, title, JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION)
{
try
{
FileWriter writer = new FileWriter(theFile);
writer.write(source.getText());
writer.close();
}
catch (IOException ie)
{
displayMessage((String) rsrcTable.get("dialogs.error"), ie.getMessage());
}
getRootComponent().setTitle((String) rsrcTable.get("remote.title") + remoteFileName);
sourceChanged = false;
source.getDocument().addDocumentListener(new AppDocHandler());
alreadySaved = true;
}
else if (result == JOptionPane.NO_OPTION)
{
this.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, (String) rsrcTable.get("menus.file.saveas")));
}
}
}
}
}
/**
* Inner class to handle the File->Save a Copy As... menu item.
*/
public class AppFileSaveACopyAsHandler implements ActionListener
{
/**
* Handles the File->Save a Copy As... event.
*
* @param e the ActionEvent fired by the File->Save a Copy As... menu item.
*/
public void actionPerformed(ActionEvent e)
{
FileDialog remoteFileDialog;
remoteFileDialog = new FileDialog(getRootComponent(), (String) rsrcTable.get("dialogs.savefileas"), FileDialog.SAVE);
remoteFileDialog.show();
remoteFileDialog.setVisible(false);
String tempName = remoteFileDialog.getFile();
String tempDir = remoteFileDialog.getDirectory();
remoteFileDialog.dispose();
if (tempName != null)
{
File theFile = new File(tempDir, tempName);
if (!theFile.exists())
{
try
{
FileWriter writer = new FileWriter(theFile);
writer.write(source.getText());
writer.close();
}
catch (IOException ie)
{
displayMessage((String) rsrcTable.get("dialogs.error"), ie.getMessage());
}
}
else
{
String title = (String) rsrcTable.get("dialogs.overwritefile");
String msg = (String) rsrcTable.get("dialogs.messages.overwritefile");
int result = JOptionPane.showConfirmDialog(getRootComponent(), msg, title, JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION)
{
try
{
FileWriter writer = new FileWriter(theFile);
writer.write(source.getText());
writer.close();
}
catch (IOException ie)
{
displayMessage((String) rsrcTable.get("dialogs.error"), ie.getMessage());
}
}
else if (result == JOptionPane.NO_OPTION)
{
this.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, (String) rsrcTable.get("menus.file.saveacopyas")));
}
}
}
}
}
/**
* Inner class to handle the File->Revert menu item.
*/
public class AppFileRevertHandler implements ActionListener
{
/**
* Handles the File->Revert event.
*
* @param e the ActionEvent fired by the File->Revert menu item.
*/
public void actionPerformed(ActionEvent e)
{
if (sourceChanged && alreadySaved)
{
String title = (String) rsrcTable.get("dialogs.revert");
String msg = (String) rsrcTable.get("dialogs.messages.revertfile");
int result = JOptionPane.showConfirmDialog(getRootComponent(), msg, title, JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION)
{
try
{
File theFile = new File(remoteFileDir, remoteFileName);
LineNumberReader theFileReader = new LineNumberReader(new FileReader(theFile));
String program = new String();
while (theFileReader.ready())
{
program += theFileReader.readLine() + System.getProperty("line.separator");
}
source.setText(program);
}
catch (FileNotFoundException fe)
{
displayMessage((String) rsrcTable.get("dialogs.error"), fe.getMessage());
}
catch (IOException ie)
{
displayMessage((String) rsrcTable.get("dialogs.error"), ie.getMessage());
}
getRootComponent().setTitle((String) rsrcTable.get("remote.title") + remoteFileName);
source.setCaretPosition(0);
alreadySaved = true;
sourceChanged = false;
source.getDocument().addDocumentListener(new AppDocHandler());
}
}
}
}
/**
* Inner class to handle the File->Quit menu item.
*/
public class AppFileQuitHandler implements ActionListener
{
/**
* Handles the File->Quit event.
*
* @param e the ActionEvent fired by the File->Quit menu item.
*/
public void actionPerformed(ActionEvent e)
{
if(sourceChanged)
{
String title = (String) rsrcTable.get("dialogs.savefile");
String msg = (String) rsrcTable.get("dialogs.messages.savefile");
int result = JOptionPane.showConfirmDialog(getRootComponent(), msg, title, JOptionPane.YES_NO_CANCEL_OPTION);
if (result == JOptionPane.YES_OPTION)
{
AppFileSaveHandler a = new AppFileSaveHandler();
a.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, (String) rsrcTable.get("menus.file.save")));
if (!sourceChanged)
{
getRootComponent().setVisible(false);
getRootComponent().dispose();
System.exit(0);
}
}
else if (result == JOptionPane.NO_OPTION)
{
getRootComponent().setVisible(false);
getRootComponent().dispose();
System.exit(0);
}
}
else
{
getRootComponent().setVisible(false);
getRootComponent().dispose();
System.exit(0);
}
}
}
/**
* Inner class to handle the Edit->Cut menu item.
*/
public class AppEditCutHandler implements ActionListener
{
/**
* Handles the Edit->Cut event.
*
* @param e the ActionEvent fired by the Edit->Cut menu item.
*/
public void actionPerformed(ActionEvent e)
{
StringSelection cut = new StringSelection(source.getSelectedText());
Clipboard clpbd = (Toolkit.getDefaultToolkit()).getSystemClipboard();
clpbd.setContents(cut, cut);
int start = source.getSelectionStart();
String temp = source.getText();
String temp2 = temp.substring(0 , start);
temp2 += temp.substring(source.getSelectionEnd(), temp.length());
source.setText(temp2);
source.select(start, start);
sourceChanged = true;
}
}
/**
* Inner class to handle the Edit->Copy menu item.
*/
public class AppEditCopyHandler implements ActionListener
{
/**
* Handles the Edit->Copy event.
*
* @param e the ActionEvent fired by the Edit->Cut menu item.
*/
public void actionPerformed(ActionEvent e)
{
if(source.getSelectionStart() != source.getSelectionEnd())
{
StringSelection copy = new StringSelection(source.getSelectedText());
Clipboard clpbd = (Toolkit.getDefaultToolkit()).getSystemClipboard();
clpbd.setContents(copy, copy);
}
}
}
/**
* Inner class to handle the Edit->Paste menu item.
*/
public class AppEditPasteHandler implements ActionListener
{
/**
* Handles the Edit->Paste event.
*
* @param e the ActionEvent fired by the Edit->Paste menu item.
*/
public void actionPerformed(ActionEvent e)
{
Clipboard clpbd = (Toolkit.getDefaultToolkit()).getSystemClipboard();
Transferable str = clpbd.getContents(getRootComponent());
if (str.isDataFlavorSupported(DataFlavor.stringFlavor))
{
String paste;
try
{
paste = (String) str.getTransferData(DataFlavor.stringFlavor);
if (source.getSelectionStart() == source.getSelectionEnd())
{
int start = source.getCaretPosition();
source.insert(paste, start);
source.select(start, start + paste.length());
}
else
{
int start = source.getCaretPosition();
String temp = source.getText();
String temp2 = temp.substring(0 , start);
temp2 += paste;
temp2 += temp.substring(source.getSelectionEnd(), temp.length());
source.setText(temp2);
source.select(start, start + paste.length());
}
sourceChanged = true;
}
catch (IOException ie)
{
displayMessage((String) rsrcTable.get("dialogs.error"), ie.getMessage());
}
catch (UnsupportedFlavorException udfe)
{
displayMessage((String) rsrcTable.get("dialogs.error"), udfe.getMessage());
}
}
}
}
/**
* Inner class to handle the Edit->Select All menu item.
*/
public class AppEditSelectAllHandler implements ActionListener
{
/**
* Handles the Edit->Select All event.
*
* @param e the ActionEvent fired by the Edit->Select All menu item.
*/
public void actionPerformed(ActionEvent e)
{
source.setSelectionStart(0);
source.setSelectionEnd(source.getText().length());
}
}
/**
* Inner class to handle the Edit->Clear menu item.
*/
public class AppEditClearHandler implements ActionListener
{
/**
* Handles the Edit->Clear event.
*
* @param e the ActionEvent fired by the Edit->Clear menu item.
*/
public void actionPerformed(ActionEvent e)
{
int start = source.getSelectionStart();
String temp = source.getText();
String temp2 = temp.substring(0 , start);
temp2 += temp.substring(source.getSelectionEnd(), temp.length());
source.setText(temp2);
source.select(start, start);
sourceChanged = true;
}
}
/**
* Inner class to handle the View->Zoom Tool menu item.
*/
public class AppViewZoomHandler implements ActionListener
{
/**
* Handles the View->Zoom Tool event.
*
* @param e the ActionEvent fired by the View->Zoom Tool menu item.
*/
public void actionPerformed(ActionEvent e)
{
// Enables and disables appropriate behaviours.
translate.setEnable(false);
rotate.setEnable(false);
zoom.setEnable(true);
zoomButton.setSelected(true);
// Sets the cursor for theViewport.
theViewport.setCursor(zoomCursor);
}
}
/**
* Inner class to handle the View->Translate Tool menu item.
*/
public class AppViewTranslateHandler implements ActionListener
{
/**
* Handles the View->Translate Tool event.
*
* @param e the ActionEvent fired by the View->Translate Tool menu item.
*/
public void actionPerformed(ActionEvent e)
{
// Enables and disables appropriate behaviours.
rotate.setEnable(false);
zoom.setEnable(false);
translate.setEnable(true);
translateButton.setSelected(true);
// Sets the cursor for theViewport.
theViewport.setCursor(translateCursor);
}
}
/**
* Inner class to handle the View->Rotate Tool menu item.
*/
public class AppViewRotateHandler implements ActionListener
{
/**
* Handles the View->Rotate Tool event.
*
* @param e the ActionEvent fired by the View->Rotate Tool menu item.
*/
public void actionPerformed(ActionEvent e)
{
// Enables and disables appropriate behaviours.
translate.setEnable(false);
zoom.setEnable(false);
rotate.setEnable(true);
rotateButton.setSelected(true);
// Sets the cursor for theViewport.
theViewport.setCursor(rotateCursor);
}
}
/**
* Inner class to handle the Simulation->Start Simulation menu item.
*/
public class AppSimStartHandler implements ActionListener
{
/**
* Handles the Simulation->Start Simulation event.
*
* @param e the ActionEvent fired by the Simulation->Start Simulation menu item.
*/
public void actionPerformed(ActionEvent e)
{
disableUI();
theRobot.home();
try
{
StringReader reader = new StringReader(source.getText());
theSimulationEngine.loadCommandQueue(reader);
theSimulationEngine.start();
start();
}
catch (SimulationEngineException see)
{
theSimulationEngine.stop();
stop();
enableUI();
displayMessage((String) rsrcTable.get("dialogs.error"), see.getMessage());
}
}
}
/**
* Inner class to handle the Simulation->Step Simulation menu item.
*/
public class AppSimStepHandler implements ActionListener
{
/**
* Handles the Simulation->Step Simulation event.
*
* @param e the ActionEvent fired by the Simulation->Step Simulation menu item.
*/
public void actionPerformed(ActionEvent e)
{
if (theSimulationEngine.isReady())
{
try
{
theSimulationEngine.step();
}
catch (Exception e1)
{
displayMessage((String) rsrcTable.get("dialogs.error"), e1.getMessage());
}
}
else
{
try
{
StringReader reader = new StringReader(source.getText());
theSimulationEngine.loadCommandQueue(reader);
theSimulationEngine.step();
}
catch (Exception e2)
{
displayMessage((String) rsrcTable.get("dialogs.error"), e2.getMessage());
}
}
}
}
/**
* Inner class to handle the Simulation->Stop Simulation menu item.
*/
public class AppSimStopHandler implements ActionListener
{
/**
* Handles the Simulation->Stop Simulation event.
*
* @param e the ActionEvent fired by the Simulation->Stop Simulation menu item.
*/
public void actionPerformed(ActionEvent e)
{
theSimulationEngine.stop();
stop();
enableUI();
}
}
/**
* Inner class to handle the Simulation->Home menu item.
*/
public class AppSimHomeHandler implements ActionListener
{
/**
* Handles the Simulation->Home event.
*
* @param e the ActionEvent fired by the Simulation->Home menu item.
*/
public void actionPerformed(ActionEvent e)
{
theRobot.home();
}
}
/**
* Inner class to handle the Options->Set Robot menu item.
*/
public class AppOptionsRobotHandler implements ActionListener
{
/**
* Handles the Options->Set Robot event.
*
* @param e the ActionEvent fired by the Options->Set Robot menu item.
*/
public void actionPerformed(ActionEvent e)
{
FileDialog remoteFileDialog = new FileDialog(getRootComponent(), (String) rsrcTable.get("dialogs.openfile"), FileDialog.LOAD);
remoteFileDialog.show();
remoteFileDialog.setVisible(false);
remoteFileName = remoteFileDialog.getFile();
remoteFileDir = remoteFileDialog.getDirectory();
remoteFileDialog.dispose();
if (remoteFileName != null)
{
try
{
getRootComponent().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
theViewport.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
RemoteObservable o = theRobot.getObservable();
Reader reader = new FileReader(new File(System.getProperty("user.dir") + System.getProperty("file.separator") + "rbt", remoteFileName));
theRobot.loadRobotModel((String) cfgTable.get("robotparser"), reader);
theRobot.setObservable(o);
javax.media.j3d.Locale locale = theUniverse.getLocale();
BranchGroup temp;
locale.replaceBranchGraph(theScene, temp = createScene());
theScene = temp;
JPanel statusPanel = (JPanel) labelPanel.getParent();
statusPanel.removeAll();
// Set up the layout constraints.
GridBagConstraints c = new GridBagConstraints();
GridBagLayout l = new GridBagLayout();
c.gridwidth = 1;
c.gridheight = 1;
c.ipadx = 2;
c.ipady = 2;
c.anchor = c.WEST;
c.fill = c.BOTH;
c.insets = new Insets(2, 2, 2, 2);
c.weightx = 1;
c.weighty = 1;
c.gridx = 0;
c.gridy = 0;
labelPanel = createStatus();
statusPanel.setLayout(l);
l.setConstraints(labelPanel, c);
statusPanel.add(labelPanel);
statusPanel.invalidate();
statusPanel.validate();
cfgTable.remove("rbt");
cfgTable.put("rbt", remoteFileName);
if (zoomButton.isSelected())
{
zoom.setEnable(true);
rotate.setEnable(false);
translate.setEnable(false);
theViewport.setCursor(zoomCursor);
}
else if (translateButton.isSelected())
{
zoom.setEnable(false);
rotate.setEnable(false);
translate.setEnable(true);
theViewport.setCursor(translateCursor);
}
else if (rotateButton.isSelected())
{
zoom.setEnable(false);
rotate.setEnable(true);
translate.setEnable(false);
theViewport.setCursor(rotateCursor);
}
getRootComponent().setCursor(Cursor.getDefaultCursor());
}
catch (FileNotFoundException fnfe)
{
displayMessage((String) rsrcTable.get("dialogs.error"), fnfe.getMessage());
}
catch (RobotParserException see)
{
displayMessage((String) rsrcTable.get("dialogs.error"), see.getMessage());
}
}
}
}
/**
* Inner class to handle the Options->Set Language menu item.
*/
public class AppOptionsLanguageHandler implements ActionListener
{
/**
* Handles the Options->Set Language event.
*
* @param e the ActionEvent fired by the Options->Set Language menu item.
*/
public void actionPerformed(ActionEvent e)
{
FileDialog remoteFileDialog = new FileDialog(getRootComponent(), (String) rsrcTable.get("dialogs.openfile"), FileDialog.LOAD);
remoteFileDialog.show();
remoteFileDialog.setVisible(false);
remoteFileName = remoteFileDialog.getFile();
remoteFileDir = remoteFileDialog.getDirectory();
remoteFileDialog.dispose();
if (remoteFileName != null)
{
if (remoteFileName.endsWith(".class"))
{
try
{
CommandParser c = CommandParser.loadParser(remoteFileName.substring(0, remoteFileName.length() - 6));
c.setNameTable(theRobot.getJointVariables().getNameTable());
theSimulationEngine.setCommandParser(c);
cfgTable.remove("commandparser");
cfgTable.put("commandparser", remoteFileName.substring(0, remoteFileName.length() - 6));
}
catch (CommandParserException cpe)
{
displayMessage((String) rsrcTable.get("dialogs.error"), (String) rsrcTable.get("errors.class"));
}
}
else
{
displayMessage((String) rsrcTable.get("dialogs.error"), (String) rsrcTable.get("errors.class"));
}
}
}
}
/**
* Inner class to handle the Options->Set Robot Parser menu item.
*/
public class AppOptionsParserHandler implements ActionListener
{
/**
* Handles the Options->Set Robot Parser event.
*
* @param e the ActionEvent fired by the Options->Set Robot Parser menu item.
*/
public void actionPerformed(ActionEvent e)
{
FileDialog remoteFileDialog = new FileDialog(getRootComponent(), (String) rsrcTable.get("dialogs.openfile"), FileDialog.LOAD);
remoteFileDialog.show();
remoteFileDialog.setVisible(false);
remoteFileName = remoteFileDialog.getFile();
remoteFileDir = remoteFileDialog.getDirectory();
remoteFileDialog.dispose();
if (remoteFileName != null)
{
if (remoteFileName.endsWith(".class"))
{
try
{
RobotParser r = RobotParser.loadParser(remoteFileName.substring(0, remoteFileName.length() - 6));
cfgTable.remove("robotparser");
cfgTable.put("robotparser", remoteFileName.substring(0, remoteFileName.length() - 6));
}
catch (RobotParserException rpe)
{
displayMessage((String) rsrcTable.get("dialogs.error"), (String) rsrcTable.get("errors.class"));
}
}
else
{
displayMessage((String) rsrcTable.get("dialogs.error"), (String) rsrcTable.get("errors.class"));
}
}
}
}
/**
* Inner class to handle the Options->Save Configuration menu item.
*/
public class AppOptionsSaveConfigHandler implements ActionListener
{
/**
* Handles the Options->Save Configuration event.
*
* @param e the ActionEvent fired by the Options->Save Configuration menu item.
*/
public void actionPerformed(ActionEvent e)
{
try
{
File theFile = new File("Config.properties");
FileWriter writer = new FileWriter(theFile);
Enumeration theConfigEnum = cfgTable.elements();
int i = 0;
while (theConfigEnum.hasMoreElements())
{
writer.write(config[i++][0] + "=" + (String) theConfigEnum.nextElement() + System.getProperty("line.separator"));
}
writer.close();
}
catch (IOException ie)
{
displayMessage((String) rsrcTable.get("dialogs.error"), ie.getMessage());
}
}
}
/**
* Inner class to handle the Help->Using Help menu item.
*/
public class AppHelpUsingHandler implements ActionListener
{
/**
* Handles the Help->Using Help event.
*
* @param e the ActionEvent fired by the Help->Using Help menu item.
*/
public void actionPerformed(ActionEvent e)
{
String location = "file:" + System.getProperty("user.dir")
+ System.getProperty("file.separator")
+ "help" + System.getProperty("file.separator")
+ "help.html";
if (helpFrame.isVisible())
{
try
{
helpFrame.setLocation(location);
helpFrame.toFront();
}
catch (MalformedURLException mfue) {}
catch (IOException ioe) {}
}
else
{
try
{
helpFrame = new HelpFrame((String) rsrcTable.get("menus.help"), location);
helpFrame.show();
}