MainFrame.java

/**
 *  Apple Worldwide Developer Technical Support
 *
 *  "Magic Oracle" sample demonstrating AppleScript for Java.
 *  User can communicate with this application via AppleScript to
 *  send a question string and receive an answer string in response
 *  
 *  tell Application "Magic Oracle"
 *       ask Oracle of Frame "oracleFrame" parameters{ "question?" }
 *  end tell
 *
 *  by Michael Hopkins, Apple Developer Technical Support
 *
 *  File:   MainFrame.java
 *
 *  Copyright ©1999 Apple Computer, Inc.
 *  All rights reserved.
 *
 *  4/99    v. 1.0  Shipped as 'Magic Oracle AppleScript for Java' sample.
 *
 *  You may incorporate this sample code into your applications without
 *  restriction, though the sample code has been provided "AS IS" and the
 *  responsibility for its operation is 100% yours.  However, what you are
 *  not permitted to do is to redistribute the source as "Apple Sample
 *  Code" after having made changes. If you're going to re-distribute the
 *  source, we require that you make it clear in the source that the code
 *  was descended from Apple Sample Code, but that you've made changes.
**/
 
import BufferedImage;
import BufferedDrawer;
import java.awt.*;
import java.awt.event.*;
 
/**
 * A class by the Magic Oracle application that is a simple extension of the 
 * java.awt.Frame class. It contains all the elements necessary to act as the
 * main window of an application.
 * @version 1.0, April 9, 1999
 * @author Michael Hopkins, Worldwide Developer Technical Support, Apple Computer Inc.
 **/
public class MainFrame extends Frame
{
    /**
     * Default constructor
     **/
    public MainFrame()
    {
        setLayout(new BorderLayout(0,0));
        setVisible(false);
        setSize(477,418);
        setBackground(new Color(12632256));
        
        panel1 = new java.awt.Panel();
        panel1.setLayout(null);
        panel1.setBounds(0,388,477,30);
        add("South", panel1);
        
        button1 = new java.awt.Button();
        button1.setLabel("Ask the Oracle");
        button1.setBounds(212,3,100,23);
        panel1.add(button1);
        
        textField1 = new java.awt.TextField();
        textField1.setText("What is thy Bidding?");
        textField1.setBounds(18,3,183,26);
        textField1.setForeground(new Color(0));
        textField1.setBackground(new Color(16777215));
        panel1.add(textField1);
        
        bufferedImage1 = new BufferedImage();
        bufferedImage1.setBounds(0,0,477,388);
        bufferedImage1.setBackground(new Color(16777215));
        add("Center", bufferedImage1);
        
        setTitle("Ask the Oracle");
        this.setName("oracleFrame");    /**
                                         * by calling setName(), we can refer to our frame as
                                         * Frame "oracleFrame" in AppleScript instead of Frame 1
                                         */
        
        SymWindow aSymWindow = new SymWindow();
        this.addWindowListener(aSymWindow);
        SymMouse aSymMouse = new SymMouse();
        bufferedImage1.addMouseListener(aSymMouse);
        SymMouseMotion aSymMouseMotion = new SymMouseMotion();
        bufferedImage1.addMouseMotionListener(aSymMouseMotion);
        SymAction lSymAction = new SymAction();
        button1.addActionListener(lSymAction);
        textField1.addActionListener(lSymAction);
        
        userInit();
    }
 
    static public void main(String args[])
    {
        (new MainFrame()).setVisible(true);
    }
    
/**
 * UserInit 
 * Loads neccessary images and prepares offscreen graphics areas
 **/
    protected void userInit()
    {
        String imagePath = "images/Ball.jpg";
        ballimage = Util.loadImage(imagePath, this);
        if (ballimage == null)
        {
            System.err.println("Could not load image \"" + imagePath + "\"");
        }
        else
        {
            bufferedImage1.setImage(ballimage);
        }
        String image = "image";
        String jpg   = ".jpg";
        images = new Image[24];
        for ( int i = 0; i < 24; i++ )
        {
            imagePath = "images/" + image + (i+1) + jpg;
            images[i] = Util.loadImage( imagePath, this);
            if (images[i] == null)
            {
                System.err.println("Could not load image \"" + imagePath + "\"");
            }   
        }
    }
        
    /**
     * Shows or hides the component depending on the boolean flag b.
     * @param b  if true, show the component; otherwise, hide the component.
     * @see java.awt.Component#isVisible
     */
    public void setVisible(boolean b)
    {
        if(b)
        {
            setLocation(50, 50);
        }   
        super.setVisible(b);
    }
    
 
    java.awt.Panel panel1;
    java.awt.Button button1;
    java.awt.TextField textField1;
    BufferedImage bufferedImage1;
 
    
    protected Image ballimage;
    protected Image images[];
    protected boolean dragging = false;
    protected Point startPoint;
    protected Fortune oracle = new Fortune();
 
    /**
     * Handle window events
     */
    class SymWindow extends java.awt.event.WindowAdapter
    {
        public void windowClosing(java.awt.event.WindowEvent event)
        {
            Object object = event.getSource();
            if (object == MainFrame.this)
                MainFrame_WindowClosing(event);
        }
    }
    
    void MainFrame_WindowClosing(java.awt.event.WindowEvent event)
    {
        setVisible(false);  // hide the Frame
        dispose();          // free the system resources
        System.exit(0);     // close the application
    }
    
    /**
     * Inner class for handling mouse events
     */
    class SymMouse extends java.awt.event.MouseAdapter
    {
       /**
        * Handle mousePressed events
        */
        public void mousePressed(java.awt.event.MouseEvent event)
        {
            Object object = event.getSource();
            if (object == bufferedImage1)
            {
                bufferedImage1_MousePressed(event);
                dragging = false;
            }
        }
    
       /**
        * Handle mouseReleased events
        */
        public void mouseReleased(java.awt.event.MouseEvent event)
        {
            Object object = event.getSource();
            if (object == bufferedImage1)
                bufferedImage1_MouseReleased(event);
            if ( dragging == true ) // user must drag the ball. Clicking on it will not invoke it
            {
                askMystic( textField1.getText() );
            }
        }
    }
 
    /**
     * Handle mouseDragged events
     */
    class SymMouseMotion extends java.awt.event.MouseMotionAdapter
    {
        public void mouseDragged(java.awt.event.MouseEvent event)
        {
            Object object = event.getSource();
            if (object == bufferedImage1)
            {
                bufferedImage1_MouseDragged(event);
                dragging = true;
            }
        }
    }
    
    /**
     * Factored routine exposed to AppleScript that performs the oracle "magic"
     * @param question Query to ask of the oracle
     * @return reponse from oracle
     */
    public String askMystic( String question )
    {
        if ( !(textField1.getText().equals( question )))
            textField1.setText( question );
        
        String s = "";
        if ( question.equals( "" )) // if no question is asked, return a canned response
        {
            animateTriangle( false );
            s = "Please ask a question";
        }   
        else                        // if there is a question, clear textfield and generate response
        {
            animateTriangle( );
            s = oracle.getResponse();
            try
            {
                Thread.sleep(150);  // delay in between frames of animation
            }
            catch (InterruptedException exc) { }
            textField1.setText("");
        }
        return s;
    }
 
    
    
    /**
     * Perform animation of floating dodecahedron 
     * @param input true if non-empty input from textfield
     */
    void animateTriangle( boolean input )
    {
        Graphics g = getGraphics();
        Point origin = new Point(bufferedImage1.getImageLocation()); 
        origin.x += 114;        // upper left corner for drawing repsonse images
        origin.y += 112;
        if ( g != null )
        {
            for ( int i = 0; i < 3; i++ )
            {
                try
                {
                    Thread.sleep(150);  // delay in between frames of animation
                }
                catch (InterruptedException exc) { }
                g.drawImage( images[i], origin.x, origin.y, this ); // draw 3 common animation frames
            }
            try
            {
                Thread.sleep(150);
            }
            catch (InterruptedException exc) { }
            if ( input )
                g.drawImage( images[oracle.generateResponseNum() + 4], origin.x, origin.y, this ); // draw response frame
            else
                g.drawImage( images[3], origin.x, origin.y, this ); // draw "Ask A ?"
        }
    }
    
    /**
     * Perform animation of floating dodecahedron 
     * This routine simulates calling this routine with a default value of true
     */
    void animateTriangle( )
    {
        animateTriangle( true );
    }
    
    /**
     * Handles mouse pressed events in the buffered image
     */
    void bufferedImage1_MousePressed(java.awt.event.MouseEvent event)
    {
        Point eLoc = event.getPoint();                  // cache click location
        Point iLoc = bufferedImage1.getImageLocation(); // cache image location
        Dimension iSize = bufferedImage1.getImageSize();
        Rectangle imageRect = new Rectangle(iLoc.x, iLoc.y, iSize.width, iSize.height);
        if (imageRect.contains(eLoc))                   // determine if click was within image
        {
            startPoint = new Point(eLoc.x - iLoc.x, eLoc.y - iLoc.y);
        }
        else
            startPoint = null;
    }
 
    /**
     * Handles mouse dragged events in the buffered image
     */
    void bufferedImage1_MouseDragged(java.awt.event.MouseEvent event)
    {
        if (startPoint != null)     // gets the location of the image, offsets it and draws
        {
            Point eLoc = event.getPoint();
            eLoc.translate(-startPoint.x, -startPoint.y);
            bufferedImage1.setImageLocation(eLoc);
            bufferedImage1.paint(getGraphics());
        }
    }
    
    /**
     * resets the startPoint of the buffered image when the mouse button is released
     */
    void bufferedImage1_MouseReleased(java.awt.event.MouseEvent event)
    {
        startPoint = null;
    }
 
    /**
     * Respond to button clicks and enter key pressed in text field
     */
    class SymAction implements java.awt.event.ActionListener
    {
        public void actionPerformed(java.awt.event.ActionEvent event)
        {
            Object object = event.getSource();
            if (object == button1)
                button1_ActionPerformed(event);
            else if (object == textField1)
                textField1_EnterHit(event);
        }
    }
 
    /**
     * Respond to "Ask Mystic" button pressed event
     */
    void button1_ActionPerformed(java.awt.event.ActionEvent event)
    {
        askMystic( textField1.getText( ));
    }
 
    /**
     * Respond enter key pressed in textfield
     */
    void textField1_EnterHit(java.awt.event.ActionEvent event)
    {
        simulateClick(button1);
    }
 
    /**
     * A function to simulate a click on the target button.
     * This will make the button draw as if it had been pressed and
     * released, and the button will fire an Action event as if
     * the button were pressed.
     * For use with the Apple MRJ 2.1 EA3 and later.
     */
    static protected void simulateClick(Button target)
    {
        if (target != null)
        {
            KeyEvent keyEvent = new KeyEvent(target, KeyEvent.KEY_PRESSED, 
                                           System.currentTimeMillis(), 0, KeyEvent.VK_ENTER, 
                                           (char)KeyEvent.VK_ENTER);
            target.dispatchEvent(keyEvent);
        }
    }
}