Example Programs

This appendix contains a few complete example programs that illustrate some of the more complex features in Perspective for Java:

ListenAndRotate

This example program primarily illustrates the use of the following methods:

/*

  * ListenAndRotate.java 03Apr98/jst
  * Copyright (c) 1998 Three D Graphics, Inc. All Rights Reserved.
  * Three D Graphics, Inc.
  * 11340 West Olympic Blvd., Suite 300, Los Angeles, CA 90064
  * (310) 553-3313
  *
  * This software is the confidential and proprietary information of
  * Three D Graphics, Inc. ("Confidential Information"). You shall
  * not disclose such Confidential Information and shall use it only
  * in accordance with the terms of the license agreement you entered
  * into with Three D Graphics.
  *
  * THREE D GRAPHICS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
  * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
  * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THREE D
  * GRAPHICS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
  * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
  * ITS DERIVATIVES
  */

import java.awt.*;
import java.applet.*;
import TDG.Perspective;
import TDG.event.TDGEvent;

public class ListenAndRotate extends Applet
{

   public static final int ACTION_NONE = 0;
   public static final int ACTION_DRAG = 1;
   public int j_Action;
   public Point startPoint, endPoint;
   public void init()
   {
      //{{INIT_CONTROLS
      setLayout (new BorderLayout (0,0));
      setSize (640,480);
      setBackground (new Color (16777215));
      //}}

      // Creation of a Chart
     perspective1 = new TDG.Perspective (this);

      // Add the Chart to the Applet
      add (perspective1);
      perspective1.setGraphType (0); /* set graph type */
      perspective1.setTitleString ("Rotate Me Now!"); /*set title string*/

      // if, I'm going to be controlling mouse clicks on the chart then
      // I have to disable the default mouse handling, or else
      // we get unsightly conflicts
      perspective1.setSelectionEnable (0);
      // Create an instance of a Class to catch mouse events on the
      // Chart
      SymMouse aSymMouse = new SymMouse();
      perspective1.addMouseListener (aSymMouse);
      perspective1.addMouseMotionListener (aSymMouse);

      // Create an instance of a Class to catch High Level Events defined
      // by Three D Graphics for Perspective for Java integration
      SymTDG lSymTDG = new SymTDG();
      perspective1.addPerspectiveListener (lSymTDG);
   }

   java.awt.Panel panel1;
   TDG.Perspective perspective1;
   class SymMouse extends java.awt.event.MouseAdapter
   implements java.awt.event.MouseMotionListener
   {
      public void mouseMoved (java.awt.event.MouseEvent event)
      {

      }
      public void mousePressed (java.awt.event.MouseEvent event)
      {
         Object object = event.getSource();
         if (object == perspective1)
            perspective1_mousePressed (event);
      }

      public void mouseDragged (java.awt.event.MouseEvent event)
      {
         Object object = event.getSource();
         if (object == perspective1)
            perspective1_mouseDragged (event);
      }

      public void mouseReleased (java.awt.event.MouseEvent event)
      {
         Object object = event.getSource();
         if (object == perspective1)
            perspective1_mouseReleased (event);

      }

   }

   void perspective1_mousePressed (java.awt.event.MouseEvent event)
   {
      j_Action = ACTION_NONE;
      System.out.println ("Mouse Event -> " + event);
      startPoint = new Point (event.getX(), event.getY());
   }

   void perspective1_mouseDragged (java.awt.event.MouseEvent event)
   {
      j_Action = ACTION_DRAG;
      System.out.println ("Mouse Event -> " + event);
      Point intermediatePoints = new Point (event.getX(), event.getY());
   }

   void perspective1_mouseReleased (java.awt.event.MouseEvent event)
   {
      System.out.println ("Mouse Event -> " + event);
      endPoint = new Point (event.getX(), event.getY());
      if (j_Action == ACTION_DRAG)
      {
         System.out.println ("Drag Happened!");
         rotateChart (startPoint, endPoint);
      }
      else
         System.out.println ("No Drag Happened!");
   }

   class SymTDG
   implements TDG.event.TDGListener
   {
      public void perspectiveEvent (TDG.event.TDGEvent event)
      {
         Object object = event.getSource();
         if (object == perspective1)
            perspective1_perspectiveEvent (event);
      }
   }

   // There are just a few High Level TDGEvents currently defined:

   /*
   * Perspective selection changed.
   * public static final int TDG_SELECTION_CHANGED = TDG_FIRST_EVENT_ID + 1;
   **
   * Apply color change to current selection, if any.
   * public static final int TDG_APPLY_COLOR = TDG_FIRST_EVENT_ID + 2;
   **
   * Notify Listeners that Preset has changed.
   * public static final int TDG_3DPRESET_CHANGED = TDG_FIRST_EVENT_ID + 3;
   **
   * Notify Listeners that GraphType has changed.
   * public static final int TDG_GRAPHTYPE_CHANGED = TDG_FIRST_EVENT_ID + 4;
   **
   * Notify Listeners that CALC has been performed.
  * public static final int TDG_CALC_PERFORMED = TDG_FIRST_EVENT_ID + 5;
   **
   * Notify Listeners that Editing State has been toggled.
   * public static final int TDG_EDITOR_STATE_TOGGLE = TDG_FIRST_EVENT_ID + 6;
   */

   void perspective1_perspectiveEvent (TDG.event.TDGEvent event)
   {
      System.out.println ("TDGEvent ID " + event.getID() + " is " + event);
      switch (event.getID())
      {
         case TDGEvent.TDG_CALC_PERFORMED:
            System.out.println ("Calc Performed!");
            break;
         default:
           // Do nothing... that's okay sometimes.
      }
   }

   void rotateChart (Point startPoint, Point endPoint)
   {
      int OpCode;
      int DEGREES; // degrees of rotation
      int MaximumDiff = 100;
      int RotationSensitivityBasis = 90;
      // We know there was a drag. So we now compute a rotation .... 
      int Xdiff = Math.abs (startPoint.x - endPoint.x);
      int Ydiff = Math.abs (startPoint.y - endPoint.y);
      if (Xdiff > MaximumDiff) Xdiff = MaximumDiff;
      if (Ydiff > MaximumDiff) Ydiff = MaximumDiff;
      if (Xdiff > Ydiff)
      {
         DEGREES = RotationSensitivityBasis * Xdiff / 100;
         if (startPoint.x > endPoint.x)
            OpCode = 3;
         else
            OpCode = 4;
       }
      else
      {
         DEGREES = RotationSensitivityBasis * Ydiff / 100;
         if (startPoint.y > endPoint.y)
            OpCode = 1;
         else
            OpCode = 2;
      }
      switch (OpCode)
      {
         // Rotation - note these are the only ops that use "relative" methods
         // (modify existing rotation matrix, instead of just numeric params).
         case 1:    // X axis Up
            perspective1.rotateCubeX (-DEGREES);
            break;
         case 2:    // X axis Down
            perspective1.rotateCubeX (DEGREES);
            break;
         case 3:    // Y axis Left
            perspective1.rotateCubeY (-DEGREES);
            break;
         case 4:    // Y axis Right
            perspective1.rotateCubeY (DEGREES);
            break;
         case 5:    // Z axis Clockwise
            perspective1.rotateCubeZ (-DEGREES);
            break;
         case 6:    // Z axis Counter-Clockwise
            perspective1.rotateCubeZ (DEGREES);
            break;
       }
         perspective1.updateParamsFromMatrix();
         perspective1.needRecalc();
   }
   //{{DECLARE_CONTROLS}}
}

FullMetalListen

This example program illustrates the use of the following methods:

/*
  * FullMetalListen.java 04May98/jst
  * Copyright (c) 1998 Three D Graphics, Inc. All Rights Reserved.
  * Three D Graphics, Inc.
  * 11340 West Olympic Blvd. Suite 300, Los Angeles, CA 90064
  * (310) 553-3313
  *
  * This software is the confidential and proprietary information of
  * Three D Graphics, Inc. ("Confidential Information"). You shall
  * not disclose such Confidential Information and shall use it only
  * in accordance with the terms of the license agreement you entered
  * into with Three D Graphics.
  *
  * THREE D GRAPHICS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
  * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
  * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THREE D
  * GRAPHICS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
  * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
  * ITS DERIVATIVES
  */

import java.awt.*;
import java.applet.*;
import tdg.Perspective;
import tdg.event.TDGEvent;
import tdg.TDGMouseState;

public class FullMetalListen extends Applet
   implements tdg.event.TDGListener, java.awt.event.ItemListener
{
   public Point startPoint, endPoint;
   public void init()
   {
     //{{INIT_CONTROLS
      setLayout (new FlowLayout (FlowLayout.RIGHT));
      setSize (600,550);
      setBackground (java.awt.Color.white);
      //}}
      aChoice = new Choice();
      aChoice.add ("3D Bar Chart");
      aChoice.add ("3D Surface Chart");
      aChoice.add ("2D Bar Chart");
      aChoice.add ("Pie Chart");
      add (aChoice);
      aChoice.addItemListener (this);
      // Creation of a Chart
      perspective1 = new tdg.Perspective (this);
      perspective1.setSize (500,350);
      perspective1.setTitleString ("Rotate Me Now Better!");
      // if I'm going to be controlling mouse clicks on the chart then
      // I have to disable the default mouse handling, or else
      // we get unsightly conflicts. You be the judge!
      perspective1.setSelectionEnable (0);
      // Create an instance of a Class to catch High Level Events defined
      // by Three D Graphics for Perspective for Java integration
      perspective1.addPerspectiveListener (this);
      perspective1.setGraphType (0); /* set graph type */
      // Add the Chart to the Applet
      add (perspective1);
      messageArea = new TextArea ("", 10, 90, TextArea.SCROLLBARS_BOTH);
      add (messageArea);
   }

   java.awt.Panel panel1;
   tdg.Perspective perspective1;
   java.awt.Choice aChoice;
   java.awt.TextArea messageArea;
   public void itemStateChanged (java.awt.event.ItemEvent e)
   {
      Object object = e.getSource();
      if (object == aChoice)
      {
         switch (aChoice.getSelectedIndex())
         {
             case 0: // 3D Bar
                perspective1.setGraphType (0);
              break;
              case 1: // 3D Surface
                perspective1.setGraphType (12);
              break;
              case 2: // 2D Side by Side Bar
                perspective1.setGraphType (17);
              break;
              case 3: // Pie
                perspective1.setGraphType (55);
              break;
         }
       }
   }

   public void perspectiveEvent (tdg.event.TDGEvent event)
   {
      Object object = event.getSource();
      if (object == perspective1)
         perspective1_perspectiveEvent (event);
   }

   // There are just a few High Level TDGEvents currently defined:

/*
* Perspective selection changed.
* public static final int TDG_SELECTION_CHANGED = TDG_FIRST_EVENT_ID + 1;
**
* Apply color change to current selection, if any.
* public static final int TDG_APPLY_COLOR = TDG_FIRST_EVENT_ID + 2;
**
* Notify Listeners that Preset has changed.
* public static final int TDG_3DPRESET_CHANGED = TDG_FIRST_EVENT_ID + 3;
**
* Notify Listeners that GraphType has changed.
* public static final int TDG_GRAPHTYPE_CHANGED = TDG_FIRST_EVENT_ID + 4;
**
* Notify Listeners that CALC has been performed.
* public static final int TDG_CALC_PERFORMED = TDG_FIRST_EVENT_ID + 5;
**
* Notify Listeners that Editing State has been toggled.
* public static final int TDG_EDITOR_STATE_TOGGLE = TDG_FIRST_EVENT_ID +6;
**
* Notify Listeners that Mouse Pressed.
* public static final int TDG_MOUSE_PRESSED = TDG_FIRST_EVENT_ID + 7;
**
* Notify Listeners that Mouse Dragged.
* public static final int TDG_MOUSE_DRAGGED = TDG_FIRST_EVENT_ID + 8;
**
* Notify Listeners that Mouse Released.
* public static final int TDG_MOUSE_RELEASED = TDG_FIRST_EVENT_ID + 9;
*/

   void perspective1_perspectiveEvent (tdg.event.TDGEvent event)
   {
      TDGMouseState Harry = null;
      switch (event.getID())
      {
         case TDGEvent.TDG_MOUSE_PRESSED:
            Harry = (TDGMouseState)event.getDataObject();
            startPoint = new Point (Harry.getMouseX(), Harry.getMouseY());
            break;
         case TDGEvent.TDG_MOUSE_DRAGGED:
            // This event occurs during the drag each time the mouse changes location.
            // This would be used in the case of providing selection feedback to the user 
            // or other operations prior to the completion of the drag.
            break;
         case TDGEvent.TDG_MOUSE_RELEASED:
            Harry = (TDGMouseState)event.getDataObject();
            endPoint = new Point (Harry.getMouseX(), Harry.getMouseY());
           if (Harry.isDrag() && perspective1.getJGraphType().is3DType())
            {
             String tempString = new String ("");
             tempString = messageArea.getText();
             if (tempString.length() > 10000)
               {
                messageArea.setText ("");
                 tempString = "";
             }
             if (tempString.length() > 0)
                  tempString = "\n";
             else
                  tempString = "";
             tempString += "Drag Happened.";
             messageArea.append (tempString);
             tempString = "\n";
             tempString += "===============================================";
               messageArea.append (tempString);
               rotateChart (startPoint, endPoint);
             }
            else
            {
               String tempString;
               String newMessage;
               tempString = messageArea.getText();
               if (tempString.length() > 10000)
               {
                   messageArea.setText ("");
                   tempString = "";
               }
               if (Harry.isShiftKey())
                  newMessage = "Shift Key is Down.";
               else
                  newMessage = "Shift Key is Up.";
               if (tempString.length() > 0)
                  tempString = "\n";
               else
                  tempString = "";
               tempString += newMessage;
               messageArea.append (tempString);
               if (Harry.isControlKey())
                  newMessage = "Control Key is Down.";
               else
                  newMessage = "Control Key is Up.";
               tempString = "\n";
               tempString += newMessage;
               messageArea.append (tempString);
               newMessage = "Element Object ID is (" + Harry.getElementObjectID()+ ")";
              tempString = "\n";
              tempString += newMessage;
              messageArea.append (tempString);
              newMessage="Element Instance ID is (" + Harry.getElementInstanceID()+")";
              tempString = "\n";
              tempString += newMessage;
              messageArea.append (tempString);
              newMessage = "Element Series ID is (" + Harry.getElementSeriesID() + ")";
              tempString = "\n";
              tempString += newMessage;
              messageArea.append (tempString);
              newMessage = "Element Group ID is (" + Harry.getElementGroupID() + ")";
              tempString = "\n";
              tempString += newMessage;
              messageArea.append (tempString);
              newMessage="Element Name is (" + Harry.getElementName()+")";
              tempString = "\n";
              tempString += newMessage;
              messageArea.append (tempString);
              newMessage = "Element Description is (" + Harry.getElementDesc() + ")";
              tempString = "\n";
              tempString += newMessage;
              messageArea.append (tempString);
              newMessage = "Element Text for Text Items is ("+Harry.getElementText()+")";
              tempString = "\n";
              tempString += newMessage;
              messageArea.append (tempString);
              newMessage = "====================================================";
              tempString = "\n";
              tempString += newMessage;
              messageArea.append (tempString);
             }
            break;
            default:   // Do nothing... that's okay sometimes.
      }
   }
   void rotateChart (Point startPoint, Point endPoint)
   {
      int OpCode;
      int DEGREES; // degrees of rotation
      int MaximumDiff = 100;
      int RotationSensitivityBasis = 90;
      // We know there was a drag. So we now compute a rotation .... 
      int Xdiff = Math.abs (startPoint.x - endPoint.x);
      int Ydiff = Math.abs (startPoint.y - endPoint.y);
      if (Xdiff > MaximumDiff)
         Xdiff = MaximumDiff;
      if (Ydiff > MaximumDiff)
         Ydiff = MaximumDiff;
      if (Xdiff > Ydiff)
      {
         DEGREES = RotationSensitivityBasis * Xdiff / 100;
         if (startPoint.x > endPoint.x)
            OpCode = 3;
         else
            OpCode = 4;
       }
      else
      {
         DEGREES = RotationSensitivityBasis * Ydiff / 100;
         if (startPoint.y > endPoint.y)
            OpCode = 1;
         else
            OpCode = 2;
       }
      switch (OpCode)
      {
         // Rotation - note these are the only ops that use "relative" methods
         // (modify existing rotation matrix, instead of just numeric params).

         case 1:     // X axis Up
            perspective1.rotateCubeX (-DEGREES);
            break;
         case 2:     // X axis Down
            perspective1.rotateCubeX (DEGREES);
            break;
         case 3:     // Y axis Left
            perspective1.rotateCubeY (-DEGREES);
            break;
         case 4:     // Y axis Right
            perspective1.rotateCubeY (DEGREES);
            break;
         case 5:     // Z axis Clockwise
            perspective1.rotateCubeZ (-DEGREES);
            break;
         case 6:     // Z axis Counter-Clockwise
            perspective1.rotateCubeZ (DEGREES);
            break;
       }
       perspective1.updateParamsFromMatrix();
       perspective1.needRecalc();
   }
   //{{DECLARE_CONTROL//}}
}

ToolTipDemoOne

This example program illustrates the use of the following methods:

/*

  * ToolTipDemoOne.java  06May98/jst
  * Copyright (c) 1998 Three D Graphics, Inc. All Rights Reserved.
  * Three D Graphics, Inc.
  * 11340 West Olympic Blvd. Suite 300, Los Angeles, CA  90064
  * (310) 553-3313
  * This software is the confidential and proprietary information of
  * Three D Graphics, Inc. ("Confidential Information").  You shall
  * not disclose such Confidential Information and shall use it only
  * in accordance with the terms of the license agreement you entered
  * into with Three D Graphics.
  * THREE D GRAPHICS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
  * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
  * BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.  THREE D
  * GRAPHICS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
  * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
  * ITS DERIVATIVES
  */

import java.awt.*;
import java.applet.*;
import tdg.Perspective;
import tdg.event.TDGEvent;
import tdg.TDGMouseState;
public class ToolTipDemoOne extends Applet
   implements
java.awt.event.ItemListener, java.awt.event.ActionListener
{
   public Point startPoint, endPoint;
   public void init()
   {
      setLayout (newFlowLayout (FlowLayout.RIGHT));
      setSize (600,480);
      setBackground (java.awt.Color.white);
      ToolTipModeCheckbox= new Checkbox ("Tool Tip Mode (false = user)");
      ToolTipModeCheckbox.setState (false);
      ToolTipModeCheckbox.addItemListener (this);
      add (ToolTipModeCheckbox);
      CustomToolTip = new TextField (50); // 50 columns minimum
      CustomToolTip.addActionListener (this);
      add (CustomToolTip);
      SetCustomToolTip = new Button ("Set Custom Tool Tip");
      SetCustomToolTip.addActionListener (this);
      add (SetCustomToolTip);
      // Creation of a Chart
      perspective1 = new tdg.Perspective (this);
      perspective1.setSize (580,380);
     
      perspective1.setTitleString ("Tell Me More About Myself!");
      // Disabling selection is slightly more Aesthetically pleasing
         perspective1.setSelectionEnable (0);
      perspective1.setGraphType (0);  /* set graph type */
      perspective1.setToolTipDisplay (true);
      perspective1.setToolTipMode (false);  // User Mode
      add (perspective1);// Add the Chart to the Applet
      GraphTypeChoice = new Choice();
      GraphTypeChoice.add ("3D Bar Chart");
      GraphTypeChoice.add ("3D Surface Chart");
      GraphTypeChoice.add ("2D Bar Chart");
      GraphTypeChoice.add ("Pie Chart");
      add (GraphTypeChoice);
      GraphTypeChoice.addItemListener (this);
   }
   java.awt.Panel panel1;
   tdg.Perspective perspective1;
   java.awt.Choice GraphTypeChoice;
   java.awt.Checkbox ToolTipModeCheckbox;
   java.awt.TextField CustomToolTip;
   java.awt.Button SetCustomToolTip;
   public void actionPerformed (java.awt.event.ActionEvent e)
   {
      Object object = e.getSource();
      if (object == SetCustomToolTip)
      {
         if (ToolTipModeCheckbox.getState())
         {
             perspective1.setDeveloperToolTip (CustomToolTip.getText());
         }
         else
         {
             perspective1.setUserToolTip (CustomToolTip.getText());
         }
       }
   }
   public void itemStateChanged (java.awt.event.ItemEvent e)
   {
      Object object = e.getSource();
      if (object == GraphTypeChoice)
      {
         switch (GraphTypeChoice.getSelectedIndex())
         {
             case 0: // 3D Bar
                perspective1.setGraphType (0);
                break;
             case 1: // 3D Surface
                perspective1.setGraphType (12);
                break;
             case 2: // 2D Side by Side Bar
                perspective1.setGraphType (17);
                break;
             case 3: // Pie
                perspective1.setGraphType (55);
                break;
         }
       }
      if (object == ToolTipModeCheckbox)
      {
         perspective1.setToolTipMode (ToolTipModeCheckbox.getState());
      }
   }
}