Interactor.java :  » Scripting » jscheme » interact » Java Open Source

Java Open Source » Scripting » jscheme 
jscheme » interact » Interactor.java
package interact;

import java.awt.Container;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.PrintWriter;
import java.io.Reader;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import jscheme.JScheme;
import jsint.InputPort;
import jsint.Procedure;
import jsint.Scheme;
import jsint.U;

/**
   An Interactor provides a window for interacting with a Jscheme
   listener that is useful for debugging Java applications.  A user
   can provide an Interactor with name value pairs that are bound as
   Jscheme global variables for easy reference.

   <p>Currently there can be only one Interactor at a time.  If a
   second one is started, because of global io variables, The old
   window will become useless.
 **/
public class Interactor implements Runnable {
  
  JFrame frame;
  private IOTextArea area;
  private IOTextArea getArea() {
    if (this.area == null) {
      this.area = new IOTextArea(rows, cols);
      this.area.setFont(new Font("monospaced", Font.PLAIN, 12)); }
    return this.area; }
      
  private Reader in;
  private Reader getReader() { 
    if (in == null) this.in =  this.getArea().getReader();
    return this.in; }
  
  private PrintWriter out;
  private PrintWriter getWriter() {
    if (out == null) out = new PrintWriter(getArea().getWriter()); 
    return this.out; }

  String name;
  int rows;
  int cols;
  Object[] pairs;
  String[] files;
  JScheme js;
  
  /**
     Start a new interactor in a new thread with Object, it, bound
     to the Jscheme global <tt>it</tt>.
   **/
  public Interactor(Object it) {this(it, new JScheme());}

  /**
     Start a new interactor in a new thread with Object, it, bound
     to the Jscheme global <tt>it</tt>.
   **/
  public Interactor(Object it, JScheme js) {this(new Object[] { "it", it }, js);}

  /**
     Start a new interactor in a new thread with the Object[], Pairs,
     providing String "name", Object value pairs that
     become Jscheme global bindings.
   **/
  public Interactor(Object[] pairs, JScheme js) {
    this(true, "Interactor", pairs, 24, 80, null, js);
  }

  /** Most general Interactor constructor.
      @param newThread Start Interactor in a new thread?
      @param name Name of JFrame.
      @param pairs Name value pairs bound to Jscheme global variables.
      @param rows Number of rows.
      @param cols Number of columns.
      @param files Additional arguments as in jsint.Scheme.main().
   **/
  public Interactor(final boolean newThread, 
        final String name, 
        final Object[] pairs, 
        final int rows, 
        final int cols, 
        final String[] files, 
                    final JScheme js) {
    this.name  = name;
    this.pairs = pairs;
    this.rows  = rows;
    this.cols  = cols;
    this.files = files;
    this.frame = createFrame();
    this.js = js;
    if (newThread) new Thread(this).start();
    else this.run();
  }
  
  private JFrame createFrame() {
    JFrame frame = new JFrame(name);
    frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
  // KRA 11OCT99: It would be nice if we could stop Scheme too.
  // But the user must do it.
  // e.getWindow().dispose(); 
  Toolkit.getDefaultToolkit().beep();
  Interactor.this.getWriter().println("Type (exit) to exit this Frame!");
      }});
    Container pane = frame.getContentPane();
    JScrollPane scroll = new JScrollPane(this.getArea()); 
    pane.add(scroll, "Center");
    frame.pack();
    frame.setVisible(true);
    return frame;
  }

  public void readEvalWriteLoop(String prompt) {
    Scheme.readEvalWriteLoop(prompt);
  }

  public void run() {
    // These should be dynamic variables!
    Scheme.pushEvaluator((jsint.Evaluator) js.getEvaluator());
    jsint.BacktraceException.printJavaTrace = true;
    jsint.Evaluator e = Scheme.currentEvaluator();
    e.setInput(new InputPort(this.getReader()));
    e.setOutput(this.getWriter());
    e.setError(this.getWriter());
    js.evalOrLoad("elf/basic.scm"); // Load some useful behavior.
    this.importVariables();
    
    if(files != null) this.loadFiles(files);
    readEvalWriteLoop("> ");
    this.frame.dispose();
    this.frame = null;
    Scheme.popEvaluator();
  }

  private void loadFiles(String[] args) {
    for(int i = 0; i < ((args == null) ? 0 : args.length); i++)
      js.evalOrLoad(args[i]);
  }

  /** Import variable value pairs.  Import the class of the value just
      to be safe.  Show the bindings so the user can use them. **/
  private void importVariables() {
    Procedure importer = ((Procedure) js.getGlobalValue("import"));
    if (pairs != null) {
      js.call("display", "Bindings:\n");
      for (int i = 0; i < pairs.length; i = i + 2)
  importVariable(((String) pairs[i]), pairs[i+1]);
    }
  }

  private void importVariable(String var, Object val) {
    js.setGlobalValue(var, val);
    js.call("import", val.getClass().getName());
    js.call("display",var + " = " + U.stringify(val) + "\n",
            Scheme.currentEvaluator().getOutput());
  }

  /**
     Run the interactor.

   **/
  public static void main(String[] args) {
    new Interactor(false, "Interactor",
       new Object[] { "now", new java.util.Date() },
       24, 80, args, new JScheme());
    System.out.println("Interaction done!");
    System.exit(0);
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.