error in java code

Hello,

I work with the educatonal model robot scorbot er III and recently found an interface written in java for controlling it. When executing the code as "java Remote" in my Windows Xp operational system, I receive the foolowing error

Exception in thread"main" java.lang.NullPointerException: Canvas3D:null GraphicsConfiguration

at javax.media.j3d.Canvas3D.checkForValidGraphicsConfig(Canvas3D.java:954)

at javax.media.j3d.Canvas3D.<init>(Canvas3D.java:997)

at RemoteCanvas3D.<init>(RemoteCanvas3D.java:50)

at Remote.<init>(Remote.java:371)

at Remote.main(Remote.java:282)

Since I am not very familiar with Java, could anyone explain me how to get over this problem?

Thank you in advance

Theodoros

[844 byte] By [Theodorosa] at [2007-11-27 6:08:31]
# 1
you have call some methods from Null objectit seems you didn't configured well the Canvas3D
eaajea at 2007-7-12 17:10:55 > top of Java-index,Java Essentials,New To Java...
# 2
Could you post the main() method and the constructor for your Remote class?
sztyopeka at 2007-7-12 17:10:55 > top of Java-index,Java Essentials,New To Java...
# 3

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();

}