Using techexplorer with Java applications


The feature described is only available in the Windows Professional Edition of techexplorer.

Using a software API called bridge2java and the techexplorer ActiveX control, the Java programmer can embed a canvas (which we call a techexplorer canvas to distinguish it from other Java canvas components) in a Java application that allows one to use techexplorer to render TeX and MathML markup on the canvas. In this document, we explain how to use this API and give two examples of its use. The API is available only on Windows platforms. The API is relatively simple to use for Java programmers, but in techexplorer 3.1 the software is still in an experimental state so users are warned that they may experience unexpected failures. The reader may find it useful, before reading the next section which is fairly technical, to skip to the sections with the two examples and execute them. This should help clarify the use/purpose of a techexplorer canvas. In each example, the background color of the techexplorer canvas is green.

The Java use discussed in this section is a different mode from that of using Java applets with techexplorer that is discussed elsewhere in the techexplorer documentation. Here we are discussing the use of Java applications. Since Java applications are stand alone programs (i.e., they do not run in a browser), we are no longer restricted to a version of Java that is implemented in a browser. In fact, the bridge2java API requires Java 1.2.2 (or later) so you must have such a version of Java installed to execute the examples described below or to use a techexplorer canvas in your Java applications.

Step-by-step instructions for using a techexplorer canvas

From the perspective of a developer, the techexplorer canvas is just another Java component that can be used in a manner similar to the use of other Java AWT components as we show in the examples. However, use of a techexplorer canvas does require some special setup to get a techexplorer ActiveX control associated with the canvas.

An ActiveXCanvas is a component that has two functions (one as an ActiveX mechanism and the other as a Java AWT mechanism). In the ActiveX world an ActiveXCanvas is a container for an ActiveX control; in the Java world it is a Java AWT component that can be added to a Java AWT container. (Now that should be confusing enough for any reader!) In our applications a techexplorer canvas is an ActiveXCanvas that contains a techexplorer ActiveX control that provides communication with the techexplorer facilities. As a Java AWT component it provides an AWT canvas component onto which the techexplorer control can draw (or render) TeX and MathML markup.

There are several things that the Java programmer has to do to use a techexplorer canvas in a Java application. They are

  1. Set up your PATH and CLASSPATH environment variables. This can be done as follows:
         #Change the next line to set the techexplorer path to the directory where techexplorer is installed
         set techexplorerPATH=
         set PATH=%PATH%;%techexplorerPATH%\bin
         set CLASSPATH=%CLASSPATH%;%techexplorerPATH%\bin\AxBridge.jar
         
    If, for example, techexplorer is installed in the directory
    C:\Program Files\IBM\techexplorer Hypermedia Browser\ then do
    set techexplorerPATH=C:\Program Files\IBM\techexplorer Hypermedia Browser
         
  2. Include the following two import statements in your Java program:
  3. Create a Java container for the techexplorer canvas. This is often a JFrame or some other kind of Java window.
  4. Include the following sequence of commands in your Java code (see the examples for complete details).
         ActiveXCanvas    activeXCanvas;        // Variable for the ActiveXCanvas
         AxTchExp         axTechExpl;           // Variable for the techexplorer ActiveX control
         ...
         try{
            //Set up the COM environment
            com.ibm.bridge2java.OleEnvironment.Initialize();
         } catch( com.ibm.bridge2java.ComException e ){
              // Code for catching the exception.  See the examples for details
         } catch ( Exception e ){
              // Code for catching any other exceptions
         }
         ...
         // The ActiveX object must be created and added to the Java container before the ActiveX
         // object can get the window handle
    
         activeXCanvas = new ActiveXCanvas;
    
         // Code for adding the activeXCanvas to the Java container.  For example, if the container
         // is a JFrame and the layout manager is a border layout manager
    
         getContentPane().add(activeXCanvas,BorderLayout.CENTER);
         setVisible(true);   // Either setVisible(), show(), or pack() must occur before creating
                             // the AxTchExp object so that the activeXCanvas isDisplayable().
         ...
         // Create the techexplorer ActiveX control and add it to the ActiveX container
    
         try{
            axTechExpl = new AxTchExp(activeXCanvas.getCanvasHwnd(),0);
         } catch( com.ibm.bridge2java.ComException e ){
            // Code to catch the exception
         } catch( Exception e ){
            // Code to catch any other exception
         }
         
  5. Use the methods from the Java techexplorer API (namely the techexplorer class) to send messages to the axTechExpl object. For example,
    axTechExpl.reloadFromTeXString(prefix + displayString + "$$");
    from the calculator code. Actually, we are not using the methods from the techexplorer class directly, but the methods from the proxy class AxTchExp.
  6. In the code that closes the container (frame or window), include
    com.ibm.bridge2java.OleEnvironment.UnInitialize();

A first example: Displaying TeX markup

In this example, we create a Java window using a JFrame. To the JFrame we add a button, a text field, and a techexplorer canvas. If the user enters TeX markup in the text field and clicks the button, the TeX markup will be rendered on the techexplorer canvas. Here is a screen shot of the Java window after the user has entered some TeX markup into the text field and clicked the button.

To see this Java application in action, open a command prompt window, go to the techexplorer directory Documentation\Help\Component\Java\, execute the setup commands shown in (1) above (if not done previously), and do the Java command

java TECanvasTest
Below is the Java code for the application with the portions related to the techexplorer canvas highlighted in red.
import java.awt.event.*                         ; // for WindowEvent, WindowListener, ActionEvent, ActionListener
import java.awt.*                               ;
import javax.swing.*                            ; // For JFrame, JTextArea, Box
import com.ibm.bridge2java.ActiveXCanvas        ;
import com.ibm.techexplorer.bridge2java.AxTchExp;

public class TECanvasTest extends JFrame implements ActionListener 
{
    // Instance fields
    private ActiveXCanvas  activeXCanvas;         // A Java canvas capable of holding an ActiveX control
    private AxTchExp       axTechExpl;            // The techexplorer ActiveX control
    private JTextArea      textArea;              // A Java textArea for TeX markup

    // Main method
    public static void main(String[] args)
    {
        TECanvasTest Test = new TECanvasTest();   // Constructor sets up and displays a
                                                  // frame containing the te enabled canvas
                                                  // plus other components that complete
    }                                             // the application.

    // Constructor
    public TECanvasTest()
    {
        super( "techexplorer Canvas Test" );// Sets the title for the frame
        setBounds(200,200,400,200);         // Position the screen at x=y=200 with width of 400 pixels
                                            // and height of 200 pixels
        // Set up the JFrame
        getContentPane().setLayout(new BorderLayout());

        JButton displayButton = new JButton("Display TeX Markup");
        displayButton.addActionListener(this);
        displayButton.setActionCommand("displayButton");

        textArea = new JTextArea();
		textArea.setBackground(Color.yellow);

        Box b = Box.createHorizontalBox();
        b.add(displayButton);
 		b.add(textArea);
        getContentPane().add("North", b);

        try {
        // Set up the COM environment.
        com.ibm.bridge2java.OleEnvironment.Initialize() ;
        }
        catch ( com.ibm.bridge2java.ComException e )
        {
            System.out.println( "COM Exception:" ) ;
            System.out.println( Long.toHexString( (e.getHResult()) ) ) ;
            System.out.println( e.getMessage() ) ;
        } catch ( Exception e )
        {
            System.out.println( "message: " + e.getMessage() ) ;
        }
        // The canvas must be created and added to the Frame before the 
        // ActiveXObject can get the window handle.
        activeXCanvas = new ActiveXCanvas();
        getContentPane().add(activeXCanvas,BorderLayout.CENTER);
        setVisible(true);                         // Make the window visible

        // Create an axTechExpl Object and put it in the canvas
        try {
            axTechExpl = new AxTchExp(activeXCanvas.getCanvasHwnd(), 0);
        } catch ( com.ibm.bridge2java.ComException e ) {
            System.out.println( "COM Exception:" ) ;
            System.out.println( Long.toHexString( (e.getHResult()) ) ) ;
            System.out.println( e.getMessage() ) ;
        } catch ( Exception e ) {
            System.out.println( "message: " + e.getMessage() ) ;
        }
        
        axTechExpl.reloadFromTeXString("\\pagecolor{lime}");  //Set background of TE canvas
        
    addWindowListener(new WindowAdapter()         // To handle window closing
       {  public void windowClosing(WindowEvent e) {  
             com.ibm.bridge2java.OleEnvironment.UnInitialize();
             System.exit(0);
          }
       } );
       
    }

    // Action Listener
    public void actionPerformed( ActionEvent e ) { 
        String action = e.getActionCommand(); 
        try {
            if (action.equals("displayButton")) {
               axTechExpl.reloadFromTeXString("\\vspace*{0.2in}" + textArea.getText());
            }

        } catch ( com.ibm.bridge2java.ComException ex ) {
            System.out.println( "COM Exception:" ) ;
            System.out.println( Long.toHexString( (ex.getHResult()) ) ) ;
            System.out.println( ex.getMessage() ) ;
        } catch ( Exception ex ) {
            System.out.println( "message: " + ex.getMessage() ) ;
        }
    }
}

One more technical point: It is natural for a Java programmer to ask, "Why not use the setBackground() method of the java.awt.Component class to set the background color of the activeXCanvas rather than using
axTechExpl.reloadFromTeXString("\\pagecolor{lime}");?"
It is possible to do this, but then techexplorer comes along and resets the background color to its default color. By using the reloadFromTeXString() method with the appropriate TeX markup, the background color is changed after techexplorer has initialized it to the default background color.

The Java source for this example can also be found in the file Documentation\Help\Component\Java\TECanvasTest.java.

A second example: A simulated symbolic calculator

In this example we use a Java application to simulate a symbolic algebraic calculator. We say, "simulate" because the calculator does not have any real calculation capabilities - just a few simulations using pattern recognition on strings. It does no "calculations" with numbers, only some simple "symbolic computations". Its purpose is to show another use of a techexplorer canvas in a more complex application. The techexplorer canvas is used to display the input and the results. Here is an image of the calculator after the "computation" of the indefinite integral of log x.

To execute this Java application, open a command line window, go to the techexplorer directory Documentation\Help\Component\Java\, set the PATH and CLASSPATH as shown in (1) above (if not done previously), and execute the Java command

java Calculator
Then use the buttons to do some calculations.

The calculator is an infix calculator (not a pre- or postfix one). Thus to calculate x*x to obtain x2 depress the following four keys: (1) the x key followed by (2) the * key followed by (3) the x key again (at this point the display should be showing x*x). Then depress (4) the = key to carry out the "computation."

For example, to compute the integral of log x, press the following three keys: (1) int, (2) log, and then (3) the = key. Try some other simple computations. If a particular computation is not implemented, the = key will not change the display.

The bak key is used to delete the "last" input or computation. The clr key completely clears the display for a new computation. Try bak or clr after computing the previous integral and then click the following keys: (1) int, (2) 1, (3) /, (4) x, and then finally (5) the = to calculate the indefinite integral of 1/x.

The bak and clr keys are idempotent. That is, two or more successive clicks of either key (without intervening inputs of other symbols) does nothing more than a single click of the key.

Below is a partial listing of the code for this application with the parts related to the use of the techexplorer canvas highlighted in red. All the deleted code is from the method calculate(). The remaining code should be sufficient to give the overall idea of how calculate() is implemented. The complete code can be found in the file Documentation\Help\Component\Java\Calculator.java.

One aspect of this application that was not present in the previous application is the class ActiveXCanvas2 that is derived from the ActiveXCanvas class. In general, when implementing a canvas class it is important to implement the getPreferredSize() and getMinimumSize() methods. These methods are used by some of the layout managers (the border layout manager in this case) to determine the amount of real estate the layout manager should apportion to the canvas. If they are not implemented, the canvas may end up too small or, as often happens, not appearing at all! It is also important to make sure that you spell the names of these methods correctly for otherwise they are just some other method (no error messages are generated) and the layout manager will not find the methods for which it is looking and the canvas may not be displayed. So if your canvas is not appearing, double check the implementation of these methods to make sure that they are done correctly.


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import com.ibm.bridge2java.ActiveXCanvas;
import com.ibm.techexplorer.bridge2java.*;      // for access to the TE APIs

class ActiveXCanvas2 extends ActiveXCanvas {
   public Dimension getPreferredSize() {        // Must have these methods for the component to show
      return(new Dimension(230,60));            // in North position when using the border layout mgr
   }
   public Dimension getMinimumSize() {          // The heights and widths used in these two methods
       return(new Dimension(225,60));           // should be relative to the frame size in which
   }                                            // the canvas is contained so the canvas will resize
                                                // properly when the frame is resized, but is not done
}                                               // for simplicity
class CalculatorFrame extends JFrame implements ActionListener {  

   // Instance fields
   private ActiveXCanvas2 activeXCanvas;
   private AxTchExp       axTechExpl;
   private final String   prefix = "\\vspace{2pt}$$";   // Used in the display of calculator results
   private String         displayString = "";           // Main part of calculator results to display
   private int            lenLastDisplayComponent = 0;  // Used by the bak button to delete last input
   
   public CalculatorFrame()
   {  setTitle("Symbolic Calculator");
      setSize(230, 250);
      getContentPane().setLayout(new BorderLayout());
      try {
         // Set up the com environment.
         com.ibm.bridge2java.OleEnvironment.Initialize() ;
      }
      catch ( com.ibm.bridge2java.ComException e ) {
          System.out.println( "COM Exception:" ) ;
          System.out.println( Long.toHexString( (e.getHResult()) ) ) ;
          System.out.println( e.getMessage() ) ;
      } catch ( Exception e ) {
          System.out.println( "message: " + e.getMessage() ) ;
      }
      // The canvas must be created and added to the Frame before the 
      // ActiveXObject can get the window handle.
      activeXCanvas = new ActiveXCanvas2();
      getContentPane().add(activeXCanvas,BorderLayout.NORTH);
      setVisible(true);     // Either setVisible() or pack() must occur before creating new 
                            // AxTchExp so that the activeXCanvas isDisplayable().

      // Create an axTechExpl Object and put it in the canvas
      try {
          axTechExpl = new AxTchExp(activeXCanvas.getCanvasHwnd(), 0);
      } catch ( com.ibm.bridge2java.ComException e ) {
          System.out.println( "COM Exception:" ) ;
          System.out.println( Long.toHexString( (e.getHResult()) ) ) ;
          System.out.println( e.getMessage() ) ;
      } catch ( Exception e ) {
          System.out.println( "message: " + e.getMessage() ) ;
      }
      axTechExpl.reloadFromTeXString("\\pagecolor{lime}");  // Set the background color of the canvas
      
      JPanel p = new JPanel();
      p.setLayout(new GridLayout(6, 4));
      addButton(p,"7");
      addButton(p,"8");
      addButton(p,"9");
      addButton(p,"clr");
      String buttons = "456/123*0x";
      for (int i = 0; i < buttons.length(); i++) 
         addButton(p, buttons.substring(i, i + 1));
      addButton(p,"bak");                   // To delete the "last" expr
      addButton(p,"-");
      addButton(p,"exp");
      addButton(p,"log");
      addButton(p,"int");
      addButton(p,"+");                     // Used to compute answer
      addButton(p,"sin");
      addButton(p,"cos");
      addButton(p,"tan");
      addButton(p,"=");                     // Clear the display
      getContentPane().add(p, "Center");
      
      addWindowListener(new WindowAdapter()         // To handle window closing
         {  public void windowClosing(WindowEvent e) {  
               com.ibm.bridge2java.OleEnvironment.UnInitialize();
               System.exit(0);
            }
         } );
   }

   private void addButton(Container c, String s)
   {  JButton b = new JButton(s);
      c.add(b);
      b.addActionListener(this);
   }
  
   public void actionPerformed(ActionEvent evt)
   {  String s = evt.getActionCommand();            // Determine which button was clicked
   
      if (s.equals("=")) {
         evaluate();                                // Carry out some simple symbolic evals
         return;
      }
      else                                          // Add new expr to display str and display
      if (s.equals("exp")||s.equals("log")||s.equals("sin")||s.equals("cos")||s.equals("tan")) {
          displayString += "\\" + s + " x";
          lenLastDisplayComponent = 6;
      }
      else if (s.equals("int")) {
              displayString += "\\int ";
              lenLastDisplayComponent = 5;
           }
      else  if (s.equals("bak")) {
               int newLen = displayString.length() - lenLastDisplayComponent;
               displayString = displayString.substring(0,newLen);
               lenLastDisplayComponent = 0;      // Can only go back one component
           }
      else if (s.equals("clr")) {
            displayString= "";                  // Clear the display
            lenLastDisplayComponent = 0;
           }
      else{
         displayString += s;
         lenLastDisplayComponent = s.length();
      }
      
      axTechExpl.reloadFromTeXString(prefix + displayString +"$$");
   }

   
   // Method for simulating evaluations
   public void evaluate() {  
      if (displayString.equals("x+x+x")||displayString.equals("2*x+x")||displayString.equals("x+2*x")){
        displayString = "3x";
        lenLastDisplayComponent = 2;
      }
      else if (displayString.equals("x+x")) {
            displayString = "2x";
            lenLastDisplayComponent = 2;
           }
      else if (displayString.equals("x-x")) {
            displayString = "0";
            lenLastDisplayComponent = 1;
           }
      else if (displayString.equals("2*x-x")||displayString.equals("x+x-x")||
              displayString.equals("x-x+x")||displayString.equals("-x+2*x")||
              displayString.equals("-x+x+x")||displayString.equals("2x-x")){
            displayString = "x";
            lenLastDisplayComponent = 1;
           }
      else if (displayString.equals("-x-x")) {
            displayString = "-2x";
            lenLastDisplayComponent = 3;
           }
      else if (displayString.equals("x*x*x")||displayString.equals("x^2*x")){
            displayString =  "x^3";
            lenLastDisplayComponent = 3;
           }

           // some code deleted

      else if (displayString.equals("1/x/x")){
            displayString =  "\\frac{1}{x^2}";
            lenLastDisplayComponent = 13;
           }
      else if (displayString.equals("\\int 1")){
            displayString = "x";
            lenLastDisplayComponent = 1;
           }
      else if (displayString.equals("\\int x")){
            displayString = "\\frac{x^2}{2}";
            lenLastDisplayComponent = 13;
           }
      else if (displayString.equals("\\int 1/x")){
            displayString = "\\log x";
            lenLastDisplayComponent = 6;
           }

           // some code deleted

           }
           
      axTechExpl.reloadFromTeXString(prefix + displayString + "$$");
   }
}

public class Calculator {  
   
   public static void main(String[] args) {
    JFrame calculator = new CalculatorFrame();
           calculator.setVisible(true);  
   }
}



Click here to to view the previous section. Click here to to view the next section.

IBM techexplorer Hypermedia Browser is a trademark of the IBM Corporation.
Send comments and questions to techexpl@us.ibm.com.
Visit the official techexplorer home page at http://www.software.ibm.com/techexplorer/.