Interacting with Java Objects
Listing 4 depicts a Java program that creates a simple GUI and then calls a script, stored in an external file, to interact with the Java frame. In this case, the BSF engine employed to execute the script is determined by the file extension.
Listing 4 ScriptedUI.java
/* This example shows how a Java app can allow a script to customize a UI */ /* Part of the BSF distribution (e.g. cf. http://jakarta.apache.org/bsf) */ import java.awt.*; import java.awt.event.*; import java.io.*; import org.apache.bsf.*; import org.apache.bsf.util.*; public class ScriptedUI { BSFManager mgr = new BSFManager (); public ScriptedUI (String fileName) { Frame f = new Frame ("Application's Main Frame"); f.addWindowListener (new WindowAdapter () { public void windowClosing (WindowEvent e) { System.exit (0); } }); Panel p = new Panel (); f.add ("Center", p); f.add ("North", new Button ("North Button")); f.add ("South", new Button ("South Button")); mgr.registerBean ("centerPanel", p); // exec script engine code to do its thing for this try { String language = BSFManager.getLangFromFilename (fileName); FileReader in = new FileReader (fileName); String script = IOUtils.getStringFromReader (in); mgr.exec (language, fileName, -1, -1, script); } catch (BSFException e) { System.err.println ("Ouch: " + e.getMessage ()); e.printStackTrace (); } catch (IOException e) { System.err.println ("Ouch: " + e.getMessage ()); e.printStackTrace (); } // now pack and show the frame f.pack (); f.show (); } public static void main (String[] args) throws Exception { if (args.length != 1) { System.err.println ("Usage: java ScriptedUI filename"); System.err.println (" where filename is the name of the script"); System.exit (1); } new ScriptedUI (args[0]); } }
The interesting part of this nutshell example is the fact that the Java program creates a Panel object and stores it in the BSF registry for use by other programs. The invoked scripts therefore are able to retrieve/refer to those Java objects and interact with them.
The Rexx BSF engine makes a function BSF() available to Rexx; this function is used to interact directly with Java using the BSF framework. In this nutshell example, the BSF() subfunctions lookupBean, invoke, registerBean, and getStaticValue are needed:
- lookupBean allows for retrieving a reference to a Java object that's stored in the BSF registry.
- invoke allows for invoking Java methods on Java objects stored in the BSF registry. Note that no typecasting is necessary on the Rexx side.
- registerBean allows for creating instances of Java classes that get stored in the BSF registry for later use.
- getStaticValue allows for retrieving the values defined with static fields of a class or interface object.
The Rexx program in Listing 5 will apply an instance of a Java BorderLayout to the panel, which allows it to address the panel's canvas with cardinal points. Then the Rexx program will create Java objects, notably a Label, two TextFields, and two Buttons. The panel's background will then be turned to yellow and the panel's parent (the frame object) will get a title indicating that its value stems from Rexx.
Listing 5 ui.rex
/* "ui.rex" - a Rexx script interacting with a Java objet */ /* pick up the center panel bean, Rexx program modeled after ui.nrx */ p = bsf("lookupBean", "centerPanel") /* reference the entry in BSF registry, put there by "ScriptedUI.class" */ /* set the layout manager to border */ call bsf "invoke", p, "setLayout", bsf("registerBean", "", "java.awt.BorderLayout") /* add a few things */ call bsf "invoke", p, "add", "Center", bsf("registerBean", "", "java.awt.Label", "Middle from Rexx") call bsf "invoke", p, "add", "North", bsf("registerBean", "", "java.awt.TextField", "North text from Rexx") call bsf "invoke", p, "add", "South", bsf("registerBean", "", "java.awt.TextField", "South from Rexx") call bsf "invoke", p, "add", "East", bsf("registerBean", "", "java.awt.Button", "Inner east from Rexx") call bsf "invoke", p, "add", "West", bsf("registerBean", "", "java.awt.Button", "Inner west from Rexx") /* configure p a bit */ call bsf "invoke", p, "setBackground", bsf("getStaticValue", "java.awt.Color", "yellow") /* configure the frame that p is in */ f = bsf("invoke", p, "getParent") call bsf "invoke", f, "setTitle", "Hello from REXX (title reset from Rexx)"
Earlier, Listing 4 depicted the Java program ScriptedUI.java, which comes with the samples in the BSF distribution. You've just seen Listing 5, which displays the Rexx program. Listing 6 gives the command line to start the program (in this case, the name of a file where the script is stored). Figure 1 shows the result of running the Java program.
Listing 6 Command line to start the Rexx program.
java ScriptedUI ui.rex
Figure 1 Using Java host objects and Java classes from Rexx.