Hi,

i made a second example, showing some basic TclBlend features.
Perhaps its a good candidate for the TclBlend docu as well.

This is demo #2, following the demo #1 javaEval example.

It will popup a Swing window with a button and demonstrates howto:

   <ul>
     <li>How to catch Swing events in Tcl (using the keyPressed event)
     <li>How to invoke a TclBlend procedure (callback) from Java by
clicking on a button
     <li>How to invoke a Java method from Tcl (changing a JButton color)

  </ul>


You need the base class file  TclJavaGlue.java  from demo #1,
and the additional files
  MyApp.java                   connecting Tcl to Swing
  MySwingApp.java       poping up a swing GUI with a button
  MyApp.tcl                      to start the stuff

Compile (jikes works as well):
     javac *.java

Invoke:
    jtclsh MyApp.tcl


I still dont understand everyting what im doing into depth,
but if you feel the examples are
correct, it would be a good idea to add a link  to the
    tclBlend1.2.2/docs/TclJava/contents.html
docu, and adding the three files to the docu.


Marcel

/*------------------------------------------------------------------------------
Name:     MyApp.java
Comment:  This may be a nice Swing application, started from a TCL script
Invoke:   jtclsh MyApp.tcl
Compile:  javac *.java
------------------------------------------------------------------------------*/
import tcl.lang.*;


/**
Example how to extend TclJavaGlue
*/
public class MyApp extends TclJavaGlue
{
  private static MySwingApp mySwingApp = null;

  public void init(tcl.lang.Interp interp)
  {
    super.init(interp);

    mySwingApp = new MySwingApp(this, "Hello TclBlend");

    System.out.println("init(): Successfully initialized MyApp");
  }

  public static MySwingApp get()
  {
    return mySwingApp;
  }

}

MyApp.tcl

/*------------------------------------------------------------------------------
Name:     MySwingApp.java
Comment:  A nice Swing application, started from a TCL script
Invoke:   jtclsh MyApp.tcl
Compile:  javac *.java
------------------------------------------------------------------------------*/
import javax.swing.*;
import java.awt.event.*;


/**
This Swing object demonstrates some TclBlend features<br> 
  <ul>
     <li>How to catch Swing events in Tcl, just press some keys ...
     <li>How to invoke a TclBlend procedure (callback) from Java by clicking on a 
button
     <li>How to invoke a method from Tcl, your button suddenly is yellow
  </ul>
Note:<br>
If you just want to catch Awt/Swing events in Tcl you should prefer to use java::bind
*/
public class MySwingApp extends JFrame
{
  private JButton clickMe = new JButton("Please click me");
  private final MyApp tcl;

  /**
  Pop up a Swing Frame with a Button
  */
  public MySwingApp(MyApp glue, String title)
  {
    super(title);
    this.tcl = glue;

    addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            MySwingApp.this.dispose();
            System.exit(0);
          }
        });


    this.getContentPane().add(clickMe);
    clickMe.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            String str = "Its nice to click me, thank you!";
            tcl.eval("tclCallback \"" + str + "\"");
          }
        });

    setBounds(250,250,200,100);
    clickMe.setBackground(java.awt.Color.white);
    show();
  }

  /**
  This method will be invoked from Tcl
  */
  public void setYellow()
  {
    clickMe.setBackground(java.awt.Color.yellow);
  }
}


/*------------------------------------------------------------------------------
Name:     TclJavaGlue.java
Comment:  Helper to connect Tcl to Java using TclBlend, allowing callbacks
          from Java to Tcl
------------------------------------------------------------------------------*/
import tcl.lang.*;


/**
This is a little wrapper for the TclBlend interface <br> 
Thru inheritance from Extension you get the interpreter of the calling Tcl script,
which can be used for callbacks back into the Tcl script
*/
public class TclJavaGlue extends tcl.lang.Extension
{
  private String myName = "TclJavaGlue: ";
  protected tcl.lang.Interp tclInterpreter = null;


  /**
  Example how to invoke from a tcl script:<br>
  <code>java::load TclJavaGlue</code>
  @param the Tcl interpreter from the calling Tcl script (tcl.lang.Extension)
  */
  public void init(tcl.lang.Interp interp)
  {
    tclInterpreter = interp;
    System.out.println(myName + "init(): Successfully initialized TclJavaGlue ...");
  }


  /**
  executing a Tcl script <br> 
  Callback to Tcl, this uses the identical Tcl interpreter which startet Java <br> 
  Example: <code>eval("puts $env(CLASSPATH)");</code>
  @param   tcl command
  @return  true: no error
  */
  public boolean eval(String tclCmd)
  {
    try {
      EventProcessor ep = new EventProcessor(tclInterpreter, tclCmd);
      tclInterpreter.getNotifier().queueEvent(ep, TCL.QUEUE_TAIL);
      ep = null;
      return true;
    }
    catch (Exception e) {
      System.out.println(myName + "Tcl interpreter internal error when evaluating " + 
tclCmd + ", EXCEPTION=" + e.toString());
      return false;
    }
  }
}


/**
  Threadsave EventProcessor for Tcl scripts called from Java <br> 
  @see http://www.cs.umn.edu/~dejong/tcl/paper.html
*/
class EventProcessor extends TclEvent
{
  private final String tclCmd;
  private final Interp tclInterpreter;
  EventProcessor(Interp interp, String cmd)
  {
    tclInterpreter = interp;
    tclCmd = cmd;
  }
  public int processEvent(int flags)
  {
    try {
      tclInterpreter.eval(tclCmd, flags);
    }
    catch (TclException e) {
      System.out.println(e.toString());
    }
    return 1;
  }
}

Reply via email to