import java.awt.event.*; import javax.swing.*; import com.genlogic.*; ////////////////////////////////////////////////////////////////////////// public class GlgAnimationDemo extends GlgJBean implements ActionListener { ////////////////////////////////////////////////////////////////////////// // The main demo class ////////////////////////////////////////////////////////////////////////// static final long serialVersionUID = 0; // Animation parameters. double M_PI = Math.PI; double DELTA = ( 2. * M_PI / 500. ); double XIncrement = DELTA * 8.; double YIncrement = DELTA * 7.; // Static variables used by GetPosition() method that generates // animation values. Values change in range 0-2*PI. double XValue = 0., YValue = 0.; // Time interval for periodic dynamic updates, in millisec. int TimeInterval = 20; double Radius; // Moving ball's radius double XMin, XMax, // Ball movement's area YMin, YMax; boolean IsReady = false; Timer timer = null; ////////////////////////////////////////////////////////////////////////// public GlgAnimationDemo() { super(); SetDResource( "$config/GlgSwingUsage", 1. ); } ////////////////////////////////////////////////////////////////////////// // Starts updates ////////////////////////////////////////////////////////////////////////// public void ReadyCallback( GlgObject viewport ) { if( GetJavaLog() ) PrintToJavaConsole( "Debug: Ready\n" ); super.ReadyCallback(); // Query the ball's radius Radius = GetDResource( "CatchMe/Radius" ); // Query the extent of the ball's movement area GlgPoint point = viewport.GetGResource( "Area/LLPoint" ); XMin = point.x; YMin = point.y; point = viewport.GetGResource( "Area/URPoint" ); XMax = point.x; YMax = point.y; if( timer == null ) { timer = new Timer( TimeInterval, this ); timer.setRepeats( true ); timer.start(); } IsReady = true; } ////////////////////////////////////////////////////////////////////////// // For use as a stand-alone java demo ////////////////////////////////////////////////////////////////////////// public static void main( final String arg[] ) { SwingUtilities. invokeLater( new Runnable(){ public void run() { Main( arg ); } } ); } ////////////////////////////////////////////////////////////////////////// public static void Main( final String arg[] ) { class DemoQuit extends WindowAdapter { public void windowClosing( WindowEvent e ) { System.exit( 0 ); } } JFrame frame = new JFrame(); frame.setResizable( true ); frame.setSize( 600, 600 ); frame.setLocation( 20, 20 ); GlgAnimationDemo animation = new GlgAnimationDemo(); frame.getContentPane().add( animation ); frame.addWindowListener( new DemoQuit() ); frame.setVisible( true ); // Setting the viewport triggers the ReadyCallback which starts // updates. animation.SetViewport( GlgObject.LoadWidget( "animation.glg", GlgObject.FILE ) ); } ////////////////////////////////////////////////////////////////////////// public void UpdateAnimation() { if( !IsReady() ) return; // Calculate new coordinates of the ball GlgPoint position = GetNewPosition(); // Set coordinates of the ball in the drawing SetDResource( "CatchMe/XValue", position.x ); SetDResource( "CatchMe/YValue", position.y ); Update(); // Make changes visible. } ////////////////////////////////////////////////////////////////////////// // This callback is invoked when user selects some object in the drawing // with the mouse. In this program, it's used to blink the moving object // (named "CatchMe") if user selects it with the mouse. ////////////////////////////////////////////////////////////////////////// public void SelectCallback( GlgObject viewport, Object[] name_array, int button ) { String name; super.SelectCallback( viewport, name_array, button ); if( name_array != null ) for( int i=0; ( name = (String) name_array[i] ) != null; ++i ) { if( name.equals( "Faster" ) || name.equals( "Slower" ) ) return; // Ignore buttons selection else if( name.equals( "CatchMe" ) ) { // In Swing, the drawing is not direct: it'll be flushed // on the screen only when finished, so we can't blink the // object's color by repetitive drawing as we do in AWT. // Instead, we toggle the ball's color to indicate a hit. int color_index = viewport.GetDResource( "CatchMe/ColorIndex" ).intValue(); viewport.SetDResource( "CatchMe/ColorIndex", color_index == 0 ? 1. : 0. ); viewport.Update(); return; } } GlgObject.Bell(); // Missed: beep'em up! } ////////////////////////////////////////////////////////////////////////// // This callback is invoked when user interacts with input objects in GLG // drawing. In this program, it is used to increase or decrease the // animation speed. ////////////////////////////////////////////////////////////////////////// public void InputCallback( GlgObject viewport, GlgObject message_obj ) { String origin, format, action; super.InputCallback( viewport, message_obj ); origin = message_obj.GetSResource( "Origin" ); format = message_obj.GetSResource( "Format" ); action = message_obj.GetSResource( "Action" ); // Handle window closing if run stand-alone if( format.equals( "Window" ) && action.equals( "DeleteWindow" ) ) System.exit( 0 ); if( format.equals( "Button" ) && action.equals( "Activate" ) ) { // Act based on the selected button. if( origin.equals( "Faster" ) ) { // Increase animation speed TimeInterval /= 2; } else if( origin.equals( "Slower" ) ) { // Decrease animation speed if( TimeInterval > 0 ) TimeInterval *= 2; else TimeInterval = 1; } if( timer != null ) timer.setDelay( TimeInterval ); } } ////////////////////////////////////////////////////////////////////////// // Stops updates ////////////////////////////////////////////////////////////////////////// public void stop() { if( timer != null ) { timer.stop(); timer = null; } IsReady = false; super.stop(); } ////////////////////////////////////////////////////////////////////////// // ActionListener method to use the bean as update timer's ActionListener. ////////////////////////////////////////////////////////////////////////// public void actionPerformed( ActionEvent e ) { if( timer != null ) UpdateAnimation(); } ////////////////////////////////////////////////////////////////////////// // Simulation: calculates the new position of the ball. ////////////////////////////////////////////////////////////////////////// public GlgPoint GetNewPosition() { GlgPoint point = new GlgPoint(); double x_center, y_center, x_amplitude, y_amplitude; // Increase x value counter XValue += XIncrement; if( XValue > 2. * M_PI ) XValue -= 2. * M_PI; // Increase y value counter YValue += YIncrement; if( YValue > 2. * M_PI ) YValue -= 2. * M_PI; // Find the center of the ball's movement area x_center = ( XMax + XMin ) / 2.; y_center = ( YMax + YMin ) / 2.; // The extent of the ball's movements x_amplitude = ( XMax - XMin ) / 2. - Radius; y_amplitude = ( YMax - YMin ) / 2. - Radius; // Calculate the ball's current position */ point.x = x_center + x_amplitude * Math.sin( XValue ); point.y = y_center + y_amplitude * Math.cos( YValue ); return point; } }