package com.craigc.progen;
import org.w3c.dom.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
/**
* Play Domain with all Run-time variabilities, Phase I
*/
class PlayRT extends Frame implements ActionListener {
Hashtable name2button = new Hashtable();// prop names to buttons
Hashtable button2name = new Hashtable();// buttons to prop names
Hashtable name2prop = new Hashtable(); // prop names to prop nodes
Document doc; // the internal representation of the XML document
public PlayRT(Document c) {
super(DOM_Util.get(c, "title", "Play Example"));
doc = c;
setLayout(new FlowLayout());
Node playNode = c.getDocumentElement();
// initialize props and hash tables
NodeList e = c.getElementsByTagName("prop");
for (int j=0; j<e.getLength(); ++j) {
Node bnode = e.item(j);
String name = DOM_Util.getAttr(bnode, "name", "?");
name2prop.put(name, bnode);
Button b = new Button();
setupProp(b, bnode);
b.addActionListener(this);
name2button.put(name, b);
button2name.put(b, name);
}
setSize(DOM_Util.getIntAttr(playNode, "width", 500),
DOM_Util.getIntAttr(playNode, "height", 250));
enterNewScene(DOM_Util.getAttr(playNode, "start", "?"));
show();
}
void enterNewScene(String sceneName) {
removeAll();
NodeList e = doc.getElementsByTagName("scene");
for (int j=0; j<e.getLength(); ++j) {
Element snode = (Element) e.item(j);
String name = DOM_Util.getAttr(snode, "name", "");
if (name.equals(sceneName)) {
// found the right scene, now add the props
setBackground(Color.decode(DOM_Util.getAttr(snode,
"color", "#ff0000")));
NodeList e2 = snode.getElementsByTagName("addprop");
for (int j2=0; j2<e2.getLength(); ++j2) {
Node pnode = e2.item(j2);
String pname = DOM_Util.getAttr(pnode, "name", "");
Button b = (Button) name2button.get(pname);
if (b!=null) {
add(b);
} else {
error("No prop named "+pname);
}
}
show();
return;
}
}
}
/** perform action when button is clicked */
public void actionPerformed(ActionEvent e) {
String pname = (String) button2name.get(e.getSource());
if (pname==null || pname.equals("")) {
error("Invalid button prop");
return;
}
Node bnode = (Node) name2prop.get(pname);
if (bnode==null) {
error("No prop named "+pname);
return;
}
NodeList e2 = ((Element)bnode).getElementsByTagName("script");
// there should only be one action script for a prop
for (int j=0; j<e2.getLength(); ++j) {
Node snode = e2.item(j);
// in phase 1, all scripts are Action scripts
setupProp((Button)name2button.get(pname), snode);
String nextScene = DOM_Util.getAttr(snode, "goto", "");
if (nextScene!=null && !nextScene.equals("")) {
enterNewScene(nextScene);
}
return; // only execute first script
}
}
void setupProp(Button b, Node bnode) {
// can't use getElementsByTagName here since there are nested
// trait elements in script elements that shouldn't be used.
for (Node n = bnode.getFirstChild(); n!=null;
n = n.getNextSibling()) {
if (n instanceof Element) {
if (n.getNodeName().equals("trait")
&& DOM_Util.getAttr(n, "name", "?").equals("Label")) {
String pname = DOM_Util.getAttr(n, "prop", "");
if (pname!=null && !pname.equals("")) {
b = (Button) name2button.get(pname);
}
if (b!=null) {
b.setLabel(DOM_Util.getContent(n));
} else {
error("Configuration error");
}
} // ignore all other traits since this is only Phase 1
}
}
}
static void error(String msg) {
System.out.println("Error: "+msg);
}
public static void main(String args[]) {
if (args.length>0) {
try {
// read XML file and start up display
Document c = DOM_Util.readDocument(args[0]);
new PlayRT(c);
} catch (Exception e) {
error("Invalid config file: "+args[0]);
}
} else {
error("No config file specified");
}
}
}
|