Java/2D Graphics GUI/Animation

Материал из Java эксперт
Перейти к: навигация, поиск

Animated Button

<source lang="java"> /**

*   Arsenal Real-Time Collaboration Server Project
*   Copyright (C) 2003  Michael Burnside, Arsenal Project
*
*   This library is free software; you can redistribute it and/or
*   modify it under the terms of the GNU Lesser General Public
*   License as published by the Free Software Foundation; either
*   version 2.1 of the License, or (at your option) any later version.
*
*   This library is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*   Lesser General Public License for more details.
*
*   You should have received a copy of the GNU Lesser General Public
*   License along with this library; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* ***************************************************************** 
*    $Header: /cvs/coolcollaborator/prod/coolcollaborator/prod/util/src/com/arsenal/util/AnimatedButton.java,v 1.1.1.1 2006/01/12 04:54:02 mburnside Exp $ 
*     
*    File: $Workfile: AnimatedButton.java $ 
*     
*    Description: 
*     
*    
*     
*    @author      michael@michaelburnside.ru (arsenal-1) 
*    @author      Michael Burnside 
*    @version     %I%, %G% 
*    @since       1.0 
*     
*/

import java.io.File; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class AnimatedButton extends JPanel {

       Font font = new Font("Arial", Font.PLAIN, 10);
       Color darkSlateGray = new Color(49,79,79);
       Color dimGray = new Color(105,105,105);
       Color slateGray = new Color(112,138,144);
       Color lightSlateGray = new Color(119,136,153);
       Color gray = new Color(190,190,190);
       Color lightGray = new Color(211,211,211);
       Color[] colors = { Color.black, darkSlateGray, dimGray, slateGray,
               lightSlateGray, gray, lightGray, Color.white };
       
 private JButton button = new JButton();
       private int fadeSpeed = 50;
       private boolean animate = false;
       private boolean allowAnimate = true; // we will animate
 private Color foreground = Color.black;
 public void setDefaultForeground(Color foreground) { this.foreground = foreground; }
 
 public AnimatedButton(String buttonText, boolean useBgImage, Color defaultForeground, boolean allowAnimate) { 
   this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
         button.setText(buttonText);
   this.foreground = defaultForeground;
         this.allowAnimate = allowAnimate;
         setOpaque(false);
         add(button);
         if(allowAnimate)
           runThread.start();
 }
       
       
       private Thread runThread = new Thread(
         new  Runnable() {    
           public void run() {
             while(true) {
              try { runThread.sleep(100); } catch(Exception e) { }       
              if(animate) {
                for(int i = 0; i < colors.length; i++) {
                  button.setForeground(colors[i]);
                  try { runThread.sleep(fadeSpeed); } catch(Exception e) { }
                }
                try { runThread.sleep(100); } catch(Exception e) { }
                for(int i = colors.length -1 ; i >= 0; i--) {
                  button.setForeground(colors[i]);      
                 try { runThread.sleep(fadeSpeed); } catch(Exception le) { }
                }
              } // end if animate
             } //end while
           }
         }
       );
       /**
        *
        * Sets the button"s and panel"s minimum size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */        
       public void setMaximumSize(int width, int height) {
          setMaximumSize(new Dimension(width, height));
          button.setMaximumSize(new Dimension(width, height));       
       }
       /**
        *
        * Sets the button"s and panel"s minimum size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */
       public void setMinimumSize(int width, int height) {
          setMinimumSize(new Dimension(width, height));
          button.setMinimumSize(new Dimension(width, height));       
       }
       /**
        *
        * Sets the button"s and panel"s preferred size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */        
       public void setPreferredSize(int width, int height) {
          setPreferredSize(new Dimension(width, height));     
          button.setPreferredSize(new Dimension(width, height));       
       }
       /**
        *
        * gets the button instance
        *
        * @return JButton component of this class
        *
        */        
       public JButton getButton() {
          return button;       
       }
       
       public void setText(String text) {
          button.setText(text);
       }
       
       public void setEnable(boolean animate) {
               if(allowAnimate) {
                 this.animate = animate;
                 if(!animate)
                   button.setForeground(Color.black);
                 button.setEnabled(animate);
               }
               else {
                 button.setEnabled(animate);
               }
       }
       

}


 </source>   



Animated Message Panel

<source lang="java"> /**

*   Arsenal Real-Time Collaboration Server Project
*   Copyright (C) 2003  Michael Burnside, Arsenal Project
*
*   This library is free software; you can redistribute it and/or
*   modify it under the terms of the GNU Lesser General Public
*   License as published by the Free Software Foundation; either
*   version 2.1 of the License, or (at your option) any later version.
*
*   This library is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*   Lesser General Public License for more details.
*
*   You should have received a copy of the GNU Lesser General Public
*   License along with this library; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* ***************************************************************** 
*    $Header: /cvs/coolcollaborator/prod/coolcollaborator/prod/util/src/com/arsenal/util/AnimatedMessagePanel.java,v 1.1.1.1 2006/01/12 04:54:02 mburnside Exp $ 
*     
*    File: $Workfile: AnimatedMessagePanel.java $ 
*     
*    Description: 
*     
*    A special panel that can scroll text messages and resize itself
*     
*    @author      michael@michaelburnside.ru (arsenal-1) 
*    @author      Michael Burnside 
*    @version     %I%, %G% 
*    @since       1.0 
*     
*/

import javax.swing.*; import javax.swing.border.*; import javax.accessibility.*; import java.awt.*; import java.awt.image.*; import java.io.*; import java.awt.event.*; import java.awt.geom.*; import java.util.Hashtable; import java.util.TreeMap; import java.util.Date; import java.util.StringTokenizer; import java.util.Enumeration; import java.awt.font.*; import java.awt.geom.*; public class AnimatedMessagePanel extends JPanel implements Runnable {

 private Graphics og = null;
 private Image offscreen = null;
 private int height = 230;
 private int width = 575;
 private int x = 0;
 private int y = 0;
 private Thread animator = null;
 private Graphics g = null;
 //private Graphics2D g2 = null;
 private boolean started = false; 
 private String[] messageQue = { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }; // size is 5
 private Font font = new Font("Arial", Font.PLAIN, 11);
 private boolean currentlyScrolling = false;
 private void setCurrentlyScrolling(boolean currentlyScrolling) { this.currentlyScrolling = currentlyScrolling; }
 private boolean isCurrentlyScrolling() { return currentlyScrolling; }
 private String[] messageWaitingQue = { "", "", "", "", "", "", "", "", "", "", "", "", "", "" }; // also size 5, its for if a message arrives while we are currently scrolling
   
 private static AnimatedMessagePanel instance = new AnimatedMessagePanel();
 public static AnimatedMessagePanel getInstance() {
   if (instance == null) {
      instance = new AnimatedMessagePanel();
   }
   return instance;
 } 
 public AnimatedMessagePanel() {
 //init();
   setWidthAndHeight();
 }
 public void init() {
   offscreen = createImage(width, height);
   og = offscreen.getGraphics();
   //g2 = (Graphics2D)og;
 }
 public void setWidthAndHeight() {
   setPreferredSize(new Dimension(width, height));
   setMinimumSize(new Dimension(width, height));
   setMaximumSize(new Dimension(width, height));
 }
 
 public void setWidthAndHeight(int width, int height) {
    this.width = width;
    this.height = height;
    setWidthAndHeight();
 }
 
 public void update(Graphics g) {
   if((offscreen != null) && (og != null))
     paint(g);
 }
 public void paint(Graphics g) {
   if((offscreen != null) && (og != null)) {
     g.drawImage(offscreen, 0, 0, null);
   }
 }
 
 public void run() {
   boolean setup = true;
   while(setup) {
     try { animator.sleep(1000); } catch(Exception e) { }
     if((offscreen != null) && (og != null)) {
       paintBG();
       printMessages();
       repaint();
       setup = false;
     }
     else {
       offscreen = createImage(width, height);
       if(offscreen != null) {
         og = offscreen.getGraphics();
         System.out.println("\n\nget og object: " + og);
         printMessages();
       }
     }
     //while(true) {
       //just loop to check for resize of component
     //  try { animator.sleep(2000); } catch(Exception e) { }
     //  if(!currentlyScrolling) {
     //    repaint();  
     //  }
     //}
     
   }
 }
 
 private void paintBG() {
   og.setColor(Color.white);
   og.fillRect(0, 0, getWidth(), getHeight());
   //og.setColor(Color.black);
 }
 
 public void start() {
   if(started) return;
   animator = new Thread(this);
   try { animator.sleep(1500); } catch(Exception e) { }
   animator.start();
   started = true;
 }
 
 public void alertNewMessage(String message) {
   addToMessageQue(message);
 }
 
 public void printMessages() {
   
     try {
         Runnable runner = new Runnable () {
           public void run () {
         
             AnimatedMessagePanel.getInstance().setCurrentlyScrolling(true);
  Graphics2D g2 = (Graphics2D)og;
             
  int linecount = 1;
  StringTokenizer st1 = new StringTokenizer(messageQue[0]);
    String text1 = "";
    String testtext1 = "";
    String prodtext1 = "";
    while(st1.hasMoreTokens()) {
      text1 = st1.nextToken();
      testtext1 += text1 + " ";
      FontRenderContext frc1 = g2.getFontRenderContext();                 
      TextLayout t11 = new TextLayout(testtext1, font, frc1);
      int sw1 = (int) t11.getBounds().getWidth();
      if(sw1 > (getWidth() - 40)) {
       linecount++;
       testtext1 = "";
       prodtext1 = text1;
      }
      else prodtext1 += text1 + " ";
    }
    
             
           
 for (int k = -(15)*(linecount-1); k <= 15; k++) {
   paintBG();
     int y = k;
     og.setColor(Color.black);
     for(int j = 0; j < messageQue.length; j++) {
       if(messageQue[j].length() != 0) {
       StringTokenizer st = new StringTokenizer(messageQue[j]);
       String text = "";
       String testtext = "";
       String prodtext = "";
       while(st.hasMoreTokens()) {
         text = st.nextToken();
         testtext += text + " ";
           FontRenderContext frc = g2.getFontRenderContext();                 
           TextLayout t1 = new TextLayout(testtext, font, frc);
           int sw = (int) t1.getBounds().getWidth();
           if(sw > (getWidth() - 40)) {
           og.drawString(prodtext, 10, y);
           y += 12;
           testtext = "";
           prodtext = text;
           }
           else prodtext += text + " ";
         }
       og.drawString(prodtext, 10, y);
         y += 18;
         if(y > getHeight()) break;
       }
     }
     repaint();
     try { Thread.sleep(50); } catch(Exception de) { }
 }
  AnimatedMessagePanel.getInstance().setCurrentlyScrolling(false);
  AnimatedMessagePanel.getInstance().checkForMessagesWaiting();
   
           }
       };
       new Thread (runner, "printMessage.run").start ();
     }
     catch ( Exception e) { }
 }
 
 private void addToMessageQue(String message) {
 if(isCurrentlyScrolling()) putMessageInWaitingQue(message);
 else {
     //first move all messages down one then add then new message to the top
     for(int i = (messageQue.length - 2); i >= 0 ; i--)  
       messageQue[i+1] = messageQue[i]; 
     messageQue[0] = message; 
     printMessages();
 }
 }
 
 private void putMessageInWaitingQue(String message) {
 for(int i = 0; i < messageWaitingQue.length; i++) {
   if(messageWaitingQue[i].length() == 0) { //nothing there, so it"s open
     messageWaitingQue[i] = message;
       break;
   }
 }
 }
 
 private boolean messageQueEmpty() {
   return  (messageWaitingQue[0].length() == 0);
 }
 
 private String getNextMessageInWaitingQue() {
 String returnStr = messageWaitingQue[0];
 adjustMessageWaitingQue();
 return returnStr;
 }
 
 private void adjustMessageWaitingQue() {
 for(int i = 0; i < (messageWaitingQue.length - 1); i++) 
   messageWaitingQue[i] = messageWaitingQue[i + 1];
   messageWaitingQue[(messageWaitingQue.length - 1)] = "";
 }
 
 private void checkForMessagesWaiting() {
   if(!messageQueEmpty()) {
   addToMessageQue(getNextMessageInWaitingQue());
 }
 }
 public void clearMessageQues() {
   for(int i = 0; i < messageQue.length; i++) messageQue[i] = ""; 
   for(int j = 0; j < messageWaitingQue.length; j++) messageWaitingQue[j] = "";
   printMessages();
 }

}


 </source>   



Animated PasswordField

<source lang="java"> /**

*   Arsenal Real-Time Collaboration Server Project
*   Copyright (C) 2003  Michael Burnside, Arsenal Project
*
*   This library is free software; you can redistribute it and/or
*   modify it under the terms of the GNU Lesser General Public
*   License as published by the Free Software Foundation; either
*   version 2.1 of the License, or (at your option) any later version.
*
*   This library is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*   Lesser General Public License for more details.
*
*   You should have received a copy of the GNU Lesser General Public
*   License along with this library; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* ***************************************************************** 
*    $Header: /cvs/coolcollaborator/prod/coolcollaborator/prod/util/src/com/arsenal/util/AnimatedPasswordField.java,v 1.1.1.1 2006/01/12 04:54:02 mburnside Exp $ 
*     
*    File: $Workfile: AnimatedPasswordField.java $ 
*     
*    Description: 
*     
*    
*     
*    @author      michael@michaelburnside.ru (arsenal-1) 
*    @author      Michael Burnside 
*    @version     %I%, %G% 
*    @since       1.0 
*     
*/

import java.io.File; import java.awt.*; import java.awt.event.*; import javax.swing.*;

public class AnimatedPasswordField extends JPanel implements FocusListener {

       Font font = new Font("Arial", Font.PLAIN, 10);
       Color darkSlateGray = new Color(49,79,79);
       Color dimGray = new Color(105,105,105);
       Color slateGray = new Color(112,138,144);
       Color lightSlateGray = new Color(119,136,153);
       Color gray = new Color(190,190,190);
       Color lightGray = new Color(211,211,211);
       Color[] colors = { Color.black, darkSlateGray, dimGray, slateGray,
               lightSlateGray, gray, lightGray, Color.white };
       
 private JPasswordField textField = new JPasswordField();
       private JLabel label = new JLabel();
       private int fadeSpeed = 50;
       private boolean animate = false;
       private boolean allowFade = false;
       private boolean fadeOut = false;
       private boolean fadeIn = false;
 private Color foreground = Color.black;
 public void setDefaultForeground(Color foreground) { this.foreground = foreground; }
       private boolean allowAnimate = true; // we will animate
 
 public AnimatedPasswordField(String labelText, boolean useBgImage, Color defaultForeground, boolean allowAnimate) { 
   this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
         label.setText(labelText);
   textField.addFocusListener(this);
         label.setBackground(colors[0]);
   textField.setBackground(colors[0]);
   this.foreground = defaultForeground;
         this.allowAnimate = allowAnimate;
         label.setForeground(foreground);
   textField.setForeground(foreground);
         add(label);
   add(textField);
     if(allowAnimate) 
         runThread.start();
       if(allowFade) {
         fadeInThread.start();
         fadeOutThread.start();
       }
         setOpaque(false);
 }
 
 public AnimatedPasswordField(String labelText, boolean useBgImage, Color defaultForeground, boolean allowAnimate, boolean allowFade) { 
     this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
           label.setText(labelText);
     textField.addFocusListener(this);
           label.setBackground(colors[0]);
     textField.setBackground(colors[0]);
     this.foreground = defaultForeground;
           this.allowAnimate = allowAnimate;
           this.allowFade = allowFade;
           label.setForeground(foreground);
     textField.setForeground(foreground);
           add(label);
     add(textField);
       if(allowAnimate) 
           runThread.start();
         if(allowFade) {
           fadeInThread.start();
           fadeOutThread.start();
         }
           setOpaque(false);
   } 
       
       
       private Thread runThread = new Thread(
         new  Runnable() {    
           public void run() {
             while(true) {
               try { runThread.sleep(100); } catch(Exception e) { }       
               if(animate) {
                 for(int i = 0; i < colors.length; i++) {
                   label.setForeground(colors[i]);
                   try { runThread.sleep(20); } catch(Exception e) { }
                 }
                 try { runThread.sleep(100); } catch(Exception e) { }
                 for(int i = colors.length -1 ; i >= 0; i--) {
                   label.setForeground(colors[i]);      
                   try { runThread.sleep(20); } catch(Exception le) { }
                 }
               } // end if animate
               label.setForeground(foreground); 
             } //end while
           }
         }
       );
    
       
       private Thread fadeInThread = new Thread(
         new  Runnable() {    
           public void run() {
              while(true) {
                if(fadeIn) {     
                  fadeIn();
                  fadeIn = false;
                }
                try { fadeInThread.sleep(fadeSpeed); } catch(Exception le) { }
              }
           }
         }
       );
       
       
       private Thread fadeOutThread = new Thread(
         new  Runnable() {    
           public void run() {
              while(true) {
                if(fadeOut) {
                  fadeOut();
                  fadeOut = false;
                }
                try { fadeOutThread.sleep(fadeSpeed); } catch(Exception le) { }
              }
           }
         }
       );
       
 public void focusGained(FocusEvent e) 
 {
       //if(allowAnimate) fadeIn();
       animate = true;
       if(allowFade) {
         fadeIn = true;
         fadeOut = false;
       }
       else {
        textField.setBackground(Color.white);
        textField.setForeground(Color.black);
       }
 }
 public void focusLost(FocusEvent e) 
 {
       //if(allowAnimate) fadeOut();
       animate = false;
       if(allowFade) {
         fadeOut = true;
         fadeIn = false;
         try { runThread.sleep(50); } catch(Exception le) { }
       }
       else {
        textField.setBackground(Color.black);
        textField.setForeground(Color.white);
       }
 }
       /**
        *
        * disable the components on this panel
        *
        */
 public void setInputsDisabled() 
 {
          setInputsEnabled(false);
 }
       /**
        *
        * enable the components on this panel
        *
        */
 public void setInputsEnabled() 
 {
          setInputsEnabled(true);
 }
       /**
        *
        * enable or disable the components on this panel
        *
        * @param enable or disable
        *
        */
 public void setInputsEnabled(boolean enable) 
 {
    textField.setEnabled(enable);
    //label.setEnabled(enable);
          if(!enable) animate = false;
 }
       /**
        *
        * are the inputs enabled
        *
        * @returns boolean
        *
        */
 public boolean areInputsEnabled() 
 {
    return textField.isEnabled();
 }        
       /**
        *
        * Sets the label"s maximum size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */         
       public void setLabelMaximumSize(int width, int height) {
          label.setMaximumSize(new Dimension(width, height));       
       }
       /**
        *
        * Sets the label"s minimum size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */
       public void setLabelMinimumSize(int width, int height) {
          label.setMinimumSize(new Dimension(width, height));       
       }
       /**
        *
        * Sets the label"s preferred size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */        
       public void setLabelPreferredSize(int width, int height) {
          label.setPreferredSize(new Dimension(width, height));       
       }
       /**
        *
        * Sets the text field"s maximum size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */
       public void setTextFieldMaximumSize(int width, int height) {
          textField.setMaximumSize(new Dimension(width, height));       
       }
       /**
        *
        * Sets the text field"s minimum size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */
       public void setTextFieldMinimumSize(int width, int height) {
          textField.setMinimumSize(new Dimension(width, height));       
       }
       /**
        *
        * Sets the text field"s preferred size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */        
       public void setTextFieldPreferredSize(int width, int height) {
          textField.setPreferredSize(new Dimension(width, height));       
       }
       /**
        *
        * Gets the text field"s value
        *
        * @return the text field value after trim()
        *
        */        
       public String getValue() {
          return textField.getText().trim();       
       }
       /**
        *
        * gets the label instance
        *
        * @return jlabel component of this class
        *
        */        
       public JLabel getLabel() {
          return label;       
       }
       /**
        *
        * gets the text field instance
        *
        * @return textfield component of this class
        *
        */        
       public JTextField getTextField() {
          return textField;       
       }
       
       public void setText(String text) {
          textField.setText(text);
       }
       
       private void fadeIn() {
         textField.setForeground(Color.black);
         for(int i = 0; i < colors.length; i++) {
           textField.setBackground(colors[i]);
           try { Thread.sleep(fadeSpeed); } catch(Exception e) { }
         }                
       }
       
       private void fadeOut() {
         textField.setForeground(Color.white);
         for(int i = colors.length -1 ; i >= 0; i--) {
           textField.setBackground(colors[i]); 
           try { Thread.sleep(fadeSpeed); } catch(Exception le) { }
         }                
       }
       

}


 </source>   



Animated TextField

<source lang="java"> /**

*   Arsenal Real-Time Collaboration Server Project
*   Copyright (C) 2003  Michael Burnside, Arsenal Project
*
*   This library is free software; you can redistribute it and/or
*   modify it under the terms of the GNU Lesser General Public
*   License as published by the Free Software Foundation; either
*   version 2.1 of the License, or (at your option) any later version.
*
*   This library is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*   Lesser General Public License for more details.
*
*   You should have received a copy of the GNU Lesser General Public
*   License along with this library; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* ***************************************************************** 
*    $Header: /cvs/coolcollaborator/prod/coolcollaborator/prod/util/src/com/arsenal/util/AnimatedTextField.java,v 1.1.1.1 2006/01/12 04:54:02 mburnside Exp $ 
*     
*    File: $Workfile: AnimatedTextField.java $ 
*     
*    Description: 
*     
*    
*     
*    @author      michael@michaelburnside.ru (arsenal-1) 
*    @author      Michael Burnside 
*    @version     %I%, %G% 
*    @since       1.0 
*     
*/

import java.io.File; import java.awt.*; import java.awt.event.*; import javax.swing.*;

public class AnimatedTextField extends JPanel implements FocusListener {

       Font font = new Font("Arial", Font.PLAIN, 10);
       Color darkSlateGray = new Color(49,79,79);
       Color dimGray = new Color(105,105,105);
       Color slateGray = new Color(112,138,144);
       Color lightSlateGray = new Color(119,136,153);
       Color gray = new Color(190,190,190);
       Color lightGray = new Color(211,211,211);
       Color[] colors = { Color.black, darkSlateGray, dimGray, slateGray,
               lightSlateGray, gray, lightGray, Color.white };
       
 private JTextField textField = new JTextField();
       private JLabel label = new JLabel();
       private int fadeSpeed = 50;
       private boolean animate = false;
       private boolean allowFade = false;
       private boolean fadeOut = false;
       private boolean fadeIn = false;
 private Color foreground = Color.black;
 public void setDefaultForeground(Color foreground) { this.foreground = foreground; }
       private boolean allowAnimate = true; // we will animate
 
 public AnimatedTextField(String labelText, boolean useBgImage, Color defaultForeground, boolean allowAnimate) { 
   this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
         label.setText(labelText);
   textField.addFocusListener(this);
         label.setBackground(colors[0]);
   textField.setBackground(colors[0]);
   this.foreground = defaultForeground;
         this.allowAnimate = allowAnimate;
         label.setForeground(foreground);
   textField.setForeground(foreground);
         add(label);
   add(textField);
         if(allowAnimate) 
           runThread.start();
         if(allowFade) {
           fadeInThread.start();
           fadeOutThread.start();
         }
         setOpaque(false);
 }
 
 public AnimatedTextField(String labelText, boolean useBgImage, Color defaultForeground, boolean allowAnimate, boolean allowFade) { 
     this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
           label.setText(labelText);
     textField.addFocusListener(this);
           label.setBackground(colors[0]);
     textField.setBackground(colors[0]);
     this.foreground = defaultForeground;
           this.allowAnimate = allowAnimate;
           this.allowFade = allowFade;
           label.setForeground(foreground);
     textField.setForeground(foreground);
           add(label);
     add(textField);
           if(allowAnimate) 
             runThread.start();
           if(allowFade) {
             fadeInThread.start();
             fadeOutThread.start();
           }
           setOpaque(false);
   } 
 
   public void addActionListener(ActionListener actionListener) {
       textField.addActionListener(actionListener);
    }
       
       
       private Thread runThread = new Thread(
         new  Runnable() {    
           public void run() {
             while(true) {
               try { runThread.sleep(100); } catch(Exception e) { }       
               if(animate) {
                 for(int i = 0; i < colors.length; i++) {
                   label.setForeground(colors[i]);
                   try { runThread.sleep(20); } catch(Exception e) { }
                 }
                 try { runThread.sleep(100); } catch(Exception e) { }
                 for(int i = colors.length -1 ; i >= 0; i--) {
                   label.setForeground(colors[i]);      
                   try { runThread.sleep(20); } catch(Exception le) { }
                 }
               } // end if animate
               label.setForeground(foreground); 
             } //end while
           }
         }
       );
    
       
       private Thread fadeInThread = new Thread(
         new  Runnable() {    
           public void run() {
              while(true) {
                if(fadeIn) {     
                  fadeIn();
                  fadeIn = false;
                }
                try { fadeInThread.sleep(fadeSpeed); } catch(Exception le) { }
              }
           }
         }
       );
       
       
       private Thread fadeOutThread = new Thread(
         new  Runnable() {    
           public void run() {
              while(true) {
                if(fadeOut) {
                  fadeOut();
                  fadeOut = false;
                }
                try { fadeOutThread.sleep(fadeSpeed); } catch(Exception le) { }
              }
           }
         }
       );
       
 public void focusGained(FocusEvent e) 
 {
          //if(allowAnimate) fadeIn();
          animate = true;
          if(allowFade) {
            fadeIn = true;
            fadeOut = false;
          }
          else {
            textField.setBackground(Color.white);
            textField.setForeground(Color.black);
          }
 }
 public void focusLost(FocusEvent e) 
 {
          //if(allowAnimate) fadeOut();
          animate = false;
          if(allowFade) {
            fadeOut = true;
            fadeIn = false;
            try { runThread.sleep(50); } catch(Exception le) { }
          }
          else {
            textField.setBackground(Color.black);
            textField.setForeground(Color.white);
          }
 }
       /**
        *
        * disable the components on this panel
        *
        */
 public void setInputsDisabled() 
 {
          setInputsEnabled(false);
 }
       /**
        *
        * enable the components on this panel
        *
        */
 public void setInputsEnabled() 
 {
          setInputsEnabled(true);
 }
       /**
        *
        * enable or disable the components on this panel
        *
        * @param enable or disable
        *
        */
 public void setInputsEnabled(boolean enable) 
 {
    textField.setEnabled(enable);
    //label.setEnabled(enable);
          if(!enable) animate = false;
 }
       /**
        *
        * are the inputs enabled
        *
        * @returns boolean
        *
        */
 public boolean areInputsEnabled() 
 {
    return textField.isEnabled();
 }        
       /**
        *
        * Sets the label"s maximum size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */         
       public void setLabelMaximumSize(int width, int height) {
          label.setMaximumSize(new Dimension(width, height));       
       }
       /**
        *
        * Sets the label"s minimum size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */
       public void setLabelMinimumSize(int width, int height) {
          label.setMinimumSize(new Dimension(width, height));       
       }
       /**
        *
        * Sets the label"s preferred size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */        
       public void setLabelPreferredSize(int width, int height) {
          label.setPreferredSize(new Dimension(width, height));       
       }
       /**
        *
        * Sets the text field"s maximum size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */
       public void setTextFieldMaximumSize(int width, int height) {
          textField.setMaximumSize(new Dimension(width, height));       
       }
       /**
        *
        * Sets the text field"s minimum size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */
       public void setTextFieldMinimumSize(int width, int height) {
          textField.setMinimumSize(new Dimension(width, height));       
       }
       /**
        *
        * Sets the text field"s preferred size
        *
        * @param width width, in pixels
        * @param height height, in pixels
        *
        */        
       public void setTextFieldPreferredSize(int width, int height) {
          textField.setPreferredSize(new Dimension(width, height));       
       }
       /**
        *
        * Gets the text field"s value
        *
        * @return the text field value after trim()
        *
        */        
       public String getValue() {
          return textField.getText().trim();       
       }
       /**
        *
        * gets the label instance
        *
        * @return jlabel component of this class
        *
        */        
       public JLabel getLabel() {
          return label;       
       }
       /**
        *
        * gets the text field instance
        *
        * @return textfield component of this class
        *
        */        
       public JTextField getTextField() {
          return textField;       
       }
       
       public void setText(String text) {
          textField.setText(text);
       }
       
       private void fadeIn() {
         textField.setForeground(Color.black);
         for(int i = 0; i < colors.length; i++) {
           textField.setBackground(colors[i]);
           try { Thread.sleep(fadeSpeed); } catch(Exception e) { }
         }                
       }
       
       private void fadeOut() {
         textField.setForeground(Color.white);
         for(int i = colors.length -1 ; i >= 0; i--) {
           textField.setBackground(colors[i]); 
           try { Thread.sleep(fadeSpeed); } catch(Exception le) { }
         }
       }
       

}


 </source>   



Animation: bounce

<source lang="java"> import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Checkbox; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Frame; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Label; import java.awt.Panel; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.event.ruponentAdapter; import java.awt.event.ruponentEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import java.text.NumberFormat; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; public class Bouncer extends JPanel implements Runnable {

 private boolean trucking = true;
 private long[] previousTimes; // milliseconds
 private int previousIndex;
 private boolean previousFilled;
 private double frameRate; // frames per second
 private Image image;
 public static void main(String[] args) {
   final Bouncer bouncer = new Bouncer();
   Frame f = new AnimationFrame(bouncer);
   f.setFont(new Font("Serif", Font.PLAIN, 12));
   f.setSize(200, 200);
   Panel controls = new Panel();
   controls.add(bouncer.createCheckbox("Anti.", Bouncer.ANTIALIASING));
   controls.add(bouncer.createCheckbox("Trans.", Bouncer.TRANSFORM));
   controls.add(bouncer.createCheckbox("Gradient", Bouncer.GRADIENT));
   controls.add(bouncer.createCheckbox("Outline", Bouncer.OUTLINE));
   controls.add(bouncer.createCheckbox("Dotted", Bouncer.DOTTED));
   controls.add(bouncer.createCheckbox("Axes", Bouncer.AXES));
   controls.add(bouncer.createCheckbox("Clip", Bouncer.CLIP));
   f.add(controls, BorderLayout.NORTH);
   f.setVisible(true);
 }
 // Tweakable variables
 private boolean mAntialiasing, mGradient, mOutline;
 private boolean mTransform, mDotted, mAxes, mClip;
 // ...and the constants that represent them. See setSwitch().
 public static final int ANTIALIASING = 0;
 public static final int GRADIENT = 1;
 public static final int OUTLINE = 2;
 public static final int TRANSFORM = 3;
 public static final int DOTTED = 4;
 public static final int AXES = 5;
 public static final int CLIP = 6;
 private float[] mPoints;
 private float[] mDeltas;
 private float mTheta;
 private int mN;
 private Shape mClipShape;
 public Bouncer() {
   previousTimes = new long[128];
   previousTimes[0] = System.currentTimeMillis();
   previousIndex = 1;
   previousFilled = false;
   mN = 38;
   mPoints = new float[mN];
   mDeltas = new float[mN];
   Random random = new Random();
   for (int i = 0; i < mN; i++) {
     mPoints[i] = random.nextFloat() * 500;
     mDeltas[i] = random.nextFloat() * 3;
   }
   addComponentListener(new ComponentAdapter() {
     public void componentResized(ComponentEvent ce) {
       Dimension d = getSize();
       for (int i = 0; i < mN; i++) {
         int limit = ((i % 2) == 0) ? d.width : d.height;
         if (mPoints[i] < 0)
           mPoints[i] = 0;
         else if (mPoints[i] >= limit)
           mPoints[i] = limit - 1;
       }
     }
   });
 }
 public void setSwitch(int item, boolean value) {
   switch (item) {
   case ANTIALIASING:
     mAntialiasing = value;
     break;
   case GRADIENT:
     mGradient = value;
     break;
   case OUTLINE:
     mOutline = value;
     break;
   case TRANSFORM:
     mTransform = value;
     break;
   case DOTTED:
     mDotted = value;
     break;
   case AXES:
     mAxes = value;
     break;
   case CLIP:
     mClip = value;
     break;
   default:
     break;
   }
 }
 protected Checkbox createCheckbox(String label, final int item) {
   Checkbox check = new Checkbox(label);
   check.addItemListener(new ItemListener() {
     public void itemStateChanged(ItemEvent ie) {
       setSwitch(item, (ie.getStateChange() == ie.SELECTED));
     }
   });
   return check;
 }
 public void timeStep() {
   Dimension d = getSize();
   for (int i = 0; i < mN; i++) {
     float value = mPoints[i] + mDeltas[i];
     int limit = ((i % 2) == 0) ? d.width : d.height;
     if (value < 0 || value > limit) {
       mDeltas[i] = -mDeltas[i];
       mPoints[i] += mDeltas[i];
     } else
       mPoints[i] = value;
   }
   mTheta += Math.PI / 192;
   if (mTheta > (2 * Math.PI))
     mTheta -= (2 * Math.PI);
 }
 public void paint(Graphics g) {
   Graphics2D g2 = (Graphics2D) g;
   setAntialiasing(g2);
   setClip(g2);
   setTransform(g2);
   Shape shape = createShape();
   setPaint(g2);
   g2.fill(shape);
   if (mOutline) {
     setStroke(g2);
     g2.setPaint(Color.blue);
     g2.draw(shape);
   }
   drawAxes(g2);
 }
 protected void setAntialiasing(Graphics2D g2) {
   if (mAntialiasing == false)
     return;
   g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
       RenderingHints.VALUE_ANTIALIAS_ON);
 }
 protected void setClip(Graphics2D g2) {
   if (mClip == false)
     return;
   if (mClipShape == null) {
     Dimension d = getSize();
     FontRenderContext frc = g2.getFontRenderContext();
     Font font = new Font("Serif", Font.PLAIN, 144);
     String s = "Java Source and Support!";
     GlyphVector gv = font.createGlyphVector(frc, s);
     Rectangle2D bounds = font.getStringBounds(s, frc);
     mClipShape = gv.getOutline(
         (d.width - (float) bounds.getWidth()) / 2,
         (d.height + (float) bounds.getHeight()) / 2);
   }
   g2.clip(mClipShape);
 }
 protected void setTransform(Graphics2D g2) {
   if (mTransform == false)
     return;
   Dimension d = getSize();
   g2.rotate(mTheta, d.width / 2, d.height / 2);
 }
 protected Shape createShape() {
   GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD,
       mPoints.length);
   path.moveTo(mPoints[0], mPoints[1]);
   for (int i = 2; i < mN; i += 6)
     path.curveTo(mPoints[i], mPoints[i + 1], mPoints[i + 2],
         mPoints[i + 3], mPoints[i + 4], mPoints[i + 5]);
   path.closePath();
   return path;
 }
 protected void setPaint(Graphics2D g2) {
   if (mGradient) {
     GradientPaint gp = new GradientPaint(0, 0, Color.yellow, 50, 25,
         Color.red, true);
     g2.setPaint(gp);
   } else
     g2.setPaint(Color.orange);
 }
 protected void setStroke(Graphics2D g2) {
   if (mDotted == false)
     return;
   Stroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT,
       BasicStroke.JOIN_ROUND, 10, new float[] { 4, 4 }, 0);
   g2.setStroke(stroke);
 }
 protected void drawAxes(Graphics2D g2) {
   if (mAxes == false)
     return;
   g2.setPaint(getForeground());
   g2.setStroke(new BasicStroke());
   Dimension d = getSize();
   int side = 20;
   int arrow = 4;
   int w = d.width / 2, h = d.height / 2;
   g2.drawLine(w - side, h, w + side, h);
   g2.drawLine(w + side - arrow, h - arrow, w + side, h);
   g2.drawLine(w, h - side, w, h + side);
   g2.drawLine(w + arrow, h + side - arrow, w, h + side);
 }
 public void run() {
   while (trucking) {
     render();
     timeStep();
     calculateFrameRate();
   }
 }
 protected void render() {
   Graphics g = getGraphics();
   if (g != null) {
     Dimension d = getSize();
     if (checkImage(d)) {
       Graphics imageGraphics = image.getGraphics();
       imageGraphics.setColor(getBackground());
       imageGraphics.fillRect(0, 0, d.width, d.height);
       imageGraphics.setColor(getForeground());
       paint(imageGraphics);
       g.drawImage(image, 0, 0, null);
       imageGraphics.dispose();
     }
     g.dispose();
   }
 }
 // Offscreen image.
 protected boolean checkImage(Dimension d) {
   if (d.width == 0 || d.height == 0)
     return false;
   if (image == null || image.getWidth(null) != d.width
       || image.getHeight(null) != d.height) {
     image = createImage(d.width, d.height);
   }
   return true;
 }
 protected void calculateFrameRate() {
   // Measure the frame rate
   long now = System.currentTimeMillis();
   int numberOfFrames = previousTimes.length;
   double newRate;
   // Use the more stable method if a history is available.
   if (previousFilled)
     newRate = (double) numberOfFrames
         / (double) (now - previousTimes[previousIndex]) * 1000.0;
   else
     newRate = 1000.0 / (double) (now - previousTimes[numberOfFrames - 1]);
   firePropertyChange("frameRate", frameRate, newRate);
   frameRate = newRate;
   // Update the history.
   previousTimes[previousIndex] = now;
   previousIndex++;
   if (previousIndex >= numberOfFrames) {
     previousIndex = 0;
     previousFilled = true;
   }
 }
 public double getFrameRate() {
   return frameRate;
 }
 // Property change support.
 private transient AnimationFrame mRateListener;
 public void setRateListener(AnimationFrame af) {
   mRateListener = af;
 }
 public void firePropertyChange(String name, double oldValue, double newValue) {
   mRateListener.rateChanged(newValue);
 }

} class AnimationFrame extends JFrame {

 private Label mStatusLabel;
 private NumberFormat mFormat;
 public AnimationFrame(Bouncer ac) {
   super();
   setLayout(new BorderLayout());
   add(ac, BorderLayout.CENTER);
   add(mStatusLabel = new Label(), BorderLayout.SOUTH);
   // Create a number formatter.
   mFormat = NumberFormat.getInstance();
   mFormat.setMaximumFractionDigits(1);
   // Listen for the frame rate changes.
   ac.setRateListener(this);
   // Kick off the animation.
   Thread t = new Thread(ac);
   t.start();
 }
 public void rateChanged(double frameRate) {
   mStatusLabel.setText(mFormat.format(frameRate) + " fps");
 }

}



 </source>   



Animator Demo

<source lang="java"> /* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* @(#)Animator.java  1.5 95/11/29 Herb Jellinek
*
* Copyright (c) 1994-1995 Sun Microsystems, Inc. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
* without fee is hereby granted.
* Please refer to the file http://java.sun.ru/copy_trademarks.html
* for further important copyright and trademark information and to
* http://java.sun.ru/licensing.html for further important licensing
* information for the Java (tm) Technology.
*
* SUN 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. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
* THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
* CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
* PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
* NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
* SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
* SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
* PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").  SUN
* SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
* HIGH RISK ACTIVITIES.
*/

import java.applet.Applet; import java.applet.AudioClip; import java.awt.Color; import java.awt.Dimension; import java.awt.Event; import java.awt.Graphics; import java.awt.Image; import java.awt.MediaTracker; import java.awt.Point; import java.awt.image.ImageProducer; import java.net.MalformedURLException; import java.net.URL; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; /**

* An applet that plays a sequence of images, as a loop or a one-shot. Can have
* a soundtrack and/or sound effects tied to individual frames.
* 
* @author Herb Jellinek
* @version 1.5, 29 Nov 1995
*/

public class Animator extends Applet implements Runnable {

 /**
  * The images, in display order (Images).
  */
 Vector images = null;
 /**
  * Duration of each image (Integers, in milliseconds).
  */
 Hashtable durations = null;
 /**
  * Sound effects for each image (AudioClips).
  */
 Hashtable sounds = null;
 /**
  * Position of each image (Points).
  */
 Hashtable positions = null;
 /**
  * MediaTracker "class" ID numbers.
  */
 static final int STARTUP_ID = 0;
 static final int BACKGROUND_ID = 1;
 static final int ANIMATION_ID = 2;
 /**
  * Start-up image URL, if any.
  */
 URL startUpImageURL = null;
 /**
  * Start-up image, if any.
  */
 Image startUpImage = null;
 /**
  * Background image URL, if any.
  */
 URL backgroundImageURL = null;
 /**
  * Background image, if any.
  */
 Image backgroundImage = null;
 /**
  * The soundtrack"s URL.
  */
 URL soundtrackURL = null;
 /**
  * The soundtrack.
  */
 AudioClip soundtrack;
 /**
  * Largest width.
  */
 int maxWidth = 0;
 /**
  * Largest height.
  */
 int maxHeight = 0;
 /**
  * Was there a problem loading the current image?
  */
 boolean imageLoadError = false;
 /**
  * The directory or URL from which the images are loaded
  */
 URL imageSource = null;
 /**
  * The directory or URL from which the sounds are loaded
  */
 URL soundSource = null;
 /**
  * The thread animating the images.
  */
 Thread engine = null;
 /**
  * The current loop slot - index into "images."
  */
 int frameNum;
 /**
  * frameNum as an Object - suitable for use as a Hashtable key.
  */
 Integer frameNumKey;
 /**
  * The current X position (for painting).
  */
 int xPos = 0;
 /**
  * The current Y position (for painting).
  */
 int yPos = 0;
 /**
  * The default number of milliseconds to wait between frames.
  */
 public static final int defaultPause = 3900;
 /**
  * The global delay between images, which can be overridden by the PAUSE
  * parameter.
  */
 int globalPause = defaultPause;
 /**
  * Whether or not the thread has been paused by the user.
  */
 boolean userPause = false;
 /**
  * Repeat the animation? If false, just play it once.
  */
 boolean repeat;
 /**
  * The offscreen image, used in double buffering
  */
 Image offScrImage;
 /**
  * The offscreen graphics context, used in double buffering
  */
 Graphics offScrGC;
 /**
  * The MediaTracker we use to load our images.
  */
 MediaTracker tracker;
 /**
  * Can we paint yet?
  */
 boolean loaded = false;
 /**
  * Was there an initialization error?
  */
 boolean error = false;
 /**
  * What we call an image file in messages.
  */
 final static String imageLabel = "image";
 /**
  * What we call a sound file in messages.
  */
 final static String soundLabel = "sound";
 /**
  * Print silly debugging info?
  */
 final boolean debug = false;
 /**
  * Applet info.
  */
 public String getAppletInfo() {
   return "Animator v1.5, by Herb Jellinek";
 }
 /**
  * Parameter info.
  */
 public String[][] getParameterInfo() {
   String[][] info = { { "imagesource", "URL", "a directory" },
       { "startup", "URL", "displayed at startup" },
       { "background", "URL", "displayed as background" },
       { "startimage", "int", "start index" },
       { "endimage", "int", "end index" },
       { "namepattern", "URL", "used to generate indexed names" },
       { "pause", "int", "milliseconds" },
       { "pauses", "ints", "milliseconds" },
       { "repeat", "boolean", "repeat or not" },
       { "positions", "coordinates", "path" },
       { "soundsource", "URL", "audio directory" },
       { "soundtrack", "URL", "background music" },
       { "sounds", "URLs", "audio samples" }, };
   return info;
 }
 /**
  * Print silly debugging info.
  */
 void dbg(String s) {
   if (debug) {
     System.out.println("> " + s);
   }
 }
 /**
  * Local version of getParameter for debugging purposes.
  */
 public String getParameter(String key) {
   String result = super.getParameter(key);
   dbg("getParameter(" + key + ") = " + result);
   return result;
 }
 final int setFrameNum(int newFrameNum) {
   frameNumKey = new Integer(frameNum = newFrameNum);
   return frameNum;
 }
 void updateMaxDims(Dimension dim) {
   maxWidth = Math.max(dim.width, maxWidth);
   maxHeight = Math.max(dim.height, maxHeight);
   dbg("New width = " + maxWidth + ", height = " + maxHeight);
 }
 /**
  * Parse the IMAGES parameter. It looks like 1|2|3|4|5, etc., where each
  * number (item) names a source image.
  * 
  * @return a Vector of (URL) image file names.
  */
 Vector parseImages(String attr) throws MalformedURLException {
   Vector result = new Vector(10);
   for (int i = 0; i < attr.length();) {
     int next = attr.indexOf("|", i);
     if (next == -1)
       next = attr.length();
     String file = attr.substring(i, next);
     result.addElement(new URL(imageSource, "T" + file + ".gif"));
     i = next + 1;
   }
   return result;
 }
 /**
  * Fetch the images named in the argument, updating maxWidth and maxHeight
  * as we go. Is restartable.
  * 
  * @param images
  *            a Vector of URLs
  * @return true if all went well, false otherwise.
  */
 boolean fetchImages(Vector images) {
   int i;
   int size = images.size();
   for (i = 0; i < size; i++) {
     Object o = images.elementAt(i);
     if (o instanceof URL) {
       URL url = (URL) o;
       tellLoadingMsg(url, imageLabel);
       Image im = getImage(url);
       tracker.addImage(im, ANIMATION_ID);
       images.setElementAt(im, i);
     }
   }
   try {
     tracker.waitForID(ANIMATION_ID);
   } catch (InterruptedException e) {
   }
   if (tracker.isErrorID(ANIMATION_ID)) {
     return false;
   }
   for (i = 0; i < size; i++) {
     updateMaxDims(getImageDimensions((Image) images.elementAt(i)));
   }
   return true;
 }
 /**
  * Parse the SOUNDS parameter. It looks like train.au||hello.au||stop.au,
  * etc., where each item refers to a source image. Empty items mean that the
  * corresponding image has no associated sound.
  * 
  * @return a Hashtable of SoundClips keyed to Integer frame numbers.
  */
 Hashtable parseSounds(String attr, Vector images)
     throws MalformedURLException {
   Hashtable result = new Hashtable();
   int imageNum = 0;
   int numImages = images.size();
   for (int i = 0; i < attr.length();) {
     if (imageNum >= numImages)
       break;
     int next = attr.indexOf("|", i);
     if (next == -1)
       next = attr.length();
     String sound = attr.substring(i, next);
     if (sound.length() != 0) {
       result.put(new Integer(imageNum), new URL(soundSource, sound));
     }
     i = next + 1;
     imageNum++;
   }
   return result;
 }
 /**
  * Fetch the sounds named in the argument. Is restartable.
  * 
  * @return URL of the first bogus file we hit, null if OK.
  */
 URL fetchSounds(Hashtable sounds) {
   for (Enumeration e = sounds.keys(); e.hasMoreElements();) {
     Integer num = (Integer) e.nextElement();
     Object o = sounds.get(num);
     if (o instanceof URL) {
       URL file = (URL) o;
       tellLoadingMsg(file, soundLabel);
       try {
         sounds.put(num, getAudioClip(file));
       } catch (Exception ex) {
         return file;
       }
     }
   }
   return null;
 }
 /**
  * Parse the PAUSES parameter. It looks like 1000|500|||750, etc., where
  * each item corresponds to a source image. Empty items mean that the
  * corresponding image has no special duration, and should use the global
  * one.
  * 
  * @return a Hashtable of Integer pauses keyed to Integer frame numbers.
  */
 Hashtable parseDurations(String attr, Vector images) {
   Hashtable result = new Hashtable();
   int imageNum = 0;
   int numImages = images.size();
   for (int i = 0; i < attr.length();) {
     if (imageNum >= numImages)
       break;
     int next = attr.indexOf("|", i);
     if (next == -1)
       next = attr.length();
     if (i != next - 1) {
       int duration = Integer.parseInt(attr.substring(i, next));
       result.put(new Integer(imageNum), new Integer(duration));
     } else {
       result.put(new Integer(imageNum), new Integer(globalPause));
     }
     i = next + 1;
     imageNum++;
   }
   return result;
 }
 /**
  * Parse a String of form xxx@yyy and return a Point.
  */
 Point parsePoint(String s) throws ParseException {
   int atPos = s.indexOf("@");
   if (atPos == -1)
     throw new ParseException("Illegal position: " + s);
   return new Point(Integer.parseInt(s.substring(0, atPos)), Integer
       .parseInt(s.substring(atPos + 1)));
 }
 /**
  * Parse the POSITIONS parameter. It looks like 10@30|11@31|||12@20, etc.,
  * where each item is an X@Y coordinate corresponding to a source image.
  * Empty items mean that the corresponding image has the same position as
  * the preceding one.
  * 
  * @return a Hashtable of Points keyed to Integer frame numbers.
  */
 Hashtable parsePositions(String param, Vector images) throws ParseException {
   Hashtable result = new Hashtable();
   int imageNum = 0;
   int numImages = images.size();
   for (int i = 0; i < param.length();) {
     if (imageNum >= numImages)
       break;
     int next = param.indexOf("|", i);
     if (next == -1)
       next = param.length();
     if (i != next) {
       result.put(new Integer(imageNum), parsePoint(param.substring(i,
           next)));
     }
     i = next + 1;
     imageNum++;
   }
   return result;
 }
 /**
  * Get the dimensions of an image.
  * 
  * @return the image"s dimensions.
  */
 Dimension getImageDimensions(Image im) {
   return new Dimension(im.getWidth(null), im.getHeight(null));
 }
 /**
  * Substitute an integer some number of times in a string, subject to
  * parameter strings embedded in the string. Parameter strings: %N -
  * substitute the integer as is, with no padding. % <digit>, for example %5 -
  * substitute the integer left-padded with zeros to <digits>digits wide. %% -
  * substitute a "%" here.
  * 
  * @param inStr
  *            the String to substitute within
  * @param theInt
  *            the int to substitute.
  */
 String doSubst(String inStr, int theInt) {
   String padStr = "0000000000";
   int length = inStr.length();
   StringBuffer result = new StringBuffer(length);
   for (int i = 0; i < length;) {
     char ch = inStr.charAt(i);
     if (ch == "%") {
       i++;
       if (i == length) {
         result.append(ch);
       } else {
         ch = inStr.charAt(i);
         if (ch == "N") {
           // just stick in the number, unmolested
           result.append(theInt + "");
           i++;
         } else {
           int pad;
           if ((pad = Character.digit(ch, 10)) != -1) {
             // we"ve got a width value
             String numStr = theInt + "";
             String scr = padStr + numStr;
             result.append(scr.substring(scr.length() - pad));
             i++;
           } else {
             result.append(ch);
             i++;
           }
         }
       }
     } else {
       result.append(ch);
       i++;
     }
   }
   return result.toString();
 }
 /**
  * Stuff a range of image names into a Vector.
  * 
  * @return a Vector of image URLs.
  */
 Vector prepareImageRange(int startImage, int endImage, String pattern)
     throws MalformedURLException {
   Vector result = new Vector(Math.abs(endImage - startImage) + 1);
   if (pattern == null) {
     pattern = "T%N.gif";
   }
   if (startImage > endImage) {
     for (int i = startImage; i >= endImage; i--) {
       result.addElement(new URL(imageSource, doSubst(pattern, i)));
     }
   } else {
     for (int i = startImage; i <= endImage; i++) {
       result.addElement(new URL(imageSource, doSubst(pattern, i)));
     }
   }
   return result;
 }
 /**
  * Initialize the applet. Get parameters.
  */
 public void init() {
   tracker = new MediaTracker(this);
   try {
     String param = getParameter("IMAGESOURCE");
     imageSource = (param == null) ? getDocumentBase() : new URL(
         getDocumentBase(), param + "/");
     param = getParameter("PAUSE");
     globalPause = (param != null) ? Integer.parseInt(param)
         : defaultPause;
     param = getParameter("REPEAT");
     repeat = (param == null) ? true
         : (param.equalsIgnoreCase("yes") || param
             .equalsIgnoreCase("true"));
     int startImage = 1;
     int endImage = 1;
     param = getParameter("ENDIMAGE");
     if (param != null) {
       endImage = Integer.parseInt(param);
       param = getParameter("STARTIMAGE");
       if (param != null) {
         startImage = Integer.parseInt(param);
       }
       param = getParameter("NAMEPATTERN");
       images = prepareImageRange(startImage, endImage, param);
     } else {
       param = getParameter("STARTIMAGE");
       if (param != null) {
         startImage = Integer.parseInt(param);
         param = getParameter("NAMEPATTERN");
         images = prepareImageRange(startImage, endImage, param);
       } else {
         param = getParameter("IMAGES");
         if (param == null) {
           showStatus("No legal IMAGES, STARTIMAGE, or ENDIMAGE "
               + "specified.");
           return;
         } else {
           images = parseImages(param);
         }
       }
     }
     param = getParameter("BACKGROUND");
     if (param != null) {
       backgroundImageURL = new URL(imageSource, param);
     }
     param = getParameter("STARTUP");
     if (param != null) {
       startUpImageURL = new URL(imageSource, param);
     }
     param = getParameter("SOUNDSOURCE");
     soundSource = (param == null) ? imageSource : new URL(
         getDocumentBase(), param + "/");
     param = getParameter("SOUNDS");
     if (param != null) {
       sounds = parseSounds(param, images);
     }
     param = getParameter("PAUSES");
     if (param != null) {
       durations = parseDurations(param, images);
     }
     param = getParameter("POSITIONS");
     if (param != null) {
       positions = parsePositions(param, images);
     }
     param = getParameter("SOUNDTRACK");
     if (param != null) {
       soundtrackURL = new URL(soundSource, param);
     }
   } catch (MalformedURLException e) {
     showParseError(e);
   } catch (ParseException e) {
     showParseError(e);
   }
   setFrameNum(0);
 }
 void tellLoadingMsg(String file, String fileType) {
   showStatus("Animator: loading " + fileType + " " + file);
 }
 void tellLoadingMsg(URL url, String fileType) {
   tellLoadingMsg(url.toExternalForm(), fileType);
 }
 void clearLoadingMessage() {
   showStatus("");
 }
 void loadError(String fileName, String fileType) {
   String errorMsg = "Animator: Couldn"t load " + fileType + " "
       + fileName;
   showStatus(errorMsg);
   System.err.println(errorMsg);
   error = true;
   repaint();
 }
 void loadError(URL badURL, String fileType) {
   loadError(badURL.toExternalForm(), fileType);
 }
 void showParseError(Exception e) {
   String errorMsg = "Animator: Parse error: " + e;
   showStatus(errorMsg);
   System.err.println(errorMsg);
   error = true;
   repaint();
 }
 void startPlaying() {
   if (soundtrack != null) {
     soundtrack.loop();
   }
 }
 void stopPlaying() {
   if (soundtrack != null) {
     soundtrack.stop();
   }
 }
 /**
  * Run the animation. This method is called by class Thread.
  * 
  * @see java.lang.Thread
  */
 public void run() {
   Thread me = Thread.currentThread();
   URL badURL;
   me.setPriority(Thread.MIN_PRIORITY);
   if (!loaded) {
     try {
       // ... to do a bunch of loading.
       if (startUpImageURL != null) {
         tellLoadingMsg(startUpImageURL, imageLabel);
         startUpImage = getImage(startUpImageURL);
         tracker.addImage(startUpImage, STARTUP_ID);
         tracker.waitForID(STARTUP_ID);
         if (tracker.isErrorID(STARTUP_ID)) {
           loadError(startUpImageURL, "start-up image");
         }
         Dimension size = getImageDimensions(startUpImage);
         resize(size.width, size.height);
         repaint();
       }
       if (backgroundImageURL != null) {
         tellLoadingMsg(backgroundImageURL, imageLabel);
         backgroundImage = getImage(backgroundImageURL);
         tracker.addImage(backgroundImage, BACKGROUND_ID);
         tracker.waitForID(BACKGROUND_ID);
         if (tracker.isErrorID(BACKGROUND_ID)) {
           loadError(backgroundImageURL, "background image");
         }
         updateMaxDims(getImageDimensions(backgroundImage));
         repaint();
       }
       // Fetch the animation frames
       if (!fetchImages(images)) {
         // Need to add method to MediaTracker to return
         // files that caused errors during loading.
         loadError("an image", imageLabel);
         return;
       }
       if (soundtrackURL != null && soundtrack == null) {
         tellLoadingMsg(soundtrackURL, imageLabel);
         soundtrack = getAudioClip(soundtrackURL);
         if (soundtrack == null) {
           loadError(soundtrackURL, "soundtrack");
           return;
         }
       }
       if (sounds != null) {
         badURL = fetchSounds(sounds);
         if (badURL != null) {
           loadError(badURL, soundLabel);
           return;
         }
       }
       clearLoadingMessage();
       offScrImage = createImage(maxWidth, maxHeight);
       offScrGC = offScrImage.getGraphics();
       offScrGC.setColor(Color.white);
       resize(maxWidth, maxHeight);
       loaded = true;
       error = false;
     } catch (Exception e) {
       error = true;
       e.printStackTrace();
     }
   }
   if (userPause) {
     return;
   }
   if (repeat || frameNum < images.size()) {
     startPlaying();
   }
   try {
     if (images.size() > 1) {
       while (maxWidth > 0 && maxHeight > 0 && engine == me) {
         if (frameNum >= images.size()) {
           if (!repeat) {
             return;
           }
           setFrameNum(0);
         }
         repaint();
         if (sounds != null) {
           AudioClip clip = (AudioClip) sounds.get(frameNumKey);
           if (clip != null) {
             clip.play();
           }
         }
         try {
           Integer pause = null;
           if (durations != null) {
             pause = (Integer) durations.get(frameNumKey);
           }
           if (pause == null) {
             Thread.sleep(globalPause);
           } else {
             Thread.sleep(pause.intValue());
           }
         } catch (InterruptedException e) {
           // Should we do anything?
         }
         setFrameNum(frameNum + 1);
       }
     }
   } finally {
     stopPlaying();
   }
 }
 /**
  * No need to clear anything; just paint.
  */
 public void update(Graphics g) {
   paint(g);
 }
 /**
  * Paint the current frame.
  */
 public void paint(Graphics g) {
   if (error || !loaded) {
     if (startUpImage != null) {
       if (tracker.checkID(STARTUP_ID)) {
         g.drawImage(startUpImage, 0, 0, this);
       }
     } else {
       if (backgroundImage != null) {
         if (tracker.checkID(BACKGROUND_ID)) {
           g.drawImage(backgroundImage, 0, 0, this);
         }
       } else {
         g.clearRect(0, 0, maxWidth, maxHeight);
       }
     }
   } else {
     if ((images != null) && (images.size() > 0)) {
       if (frameNum < images.size()) {
         if (backgroundImage == null) {
           offScrGC.fillRect(0, 0, maxWidth, maxHeight);
         } else {
           offScrGC.drawImage(backgroundImage, 0, 0, this);
         }
         Image image = (Image) images.elementAt(frameNum);
         Point pos = null;
         if (positions != null) {
           pos = (Point) positions.get(frameNumKey);
         }
         if (pos != null) {
           xPos = pos.x;
           yPos = pos.y;
         }
         offScrGC.drawImage(image, xPos, yPos, this);
         g.drawImage(offScrImage, 0, 0, this);
       } else {
         // no more animation, but need to draw something
         dbg("No more animation; drawing last image.");
         if (backgroundImage == null) {
           g.fillRect(0, 0, maxWidth, maxHeight);
         } else {
           g.drawImage(backgroundImage, 0, 0, this);
         }
         g.drawImage((Image) images.lastElement(), 0, 0, this);
       }
     }
   }
 }
 /**
  * Start the applet by forking an animation thread.
  */
 public void start() {
   if (engine == null) {
     engine = new Thread(this);
     engine.start();
   }
 }
 /**
  * Stop the insanity, um, applet.
  */
 public void stop() {
   if (engine != null && engine.isAlive()) {
     engine.stop();
   }
   engine = null;
 }
 /**
  * Pause the thread when the user clicks the mouse in the applet. If the
  * thread has stopped (as in a non-repeat performance), restart it.
  */
 public boolean handleEvent(Event evt) {
   if (evt.id == Event.MOUSE_DOWN) {
     if (loaded) {
       if (engine != null && engine.isAlive()) {
         if (userPause) {
           engine.resume();
           startPlaying();
         } else {
           engine.suspend();
           stopPlaying();
         }
         userPause = !userPause;
       } else {
         userPause = false;
         setFrameNum(0);
         engine = new Thread(this);
         engine.start();
       }
     }
     return true;
   } else {
     return super.handleEvent(evt);
   }
 }

} class ParseException extends Exception {

 ParseException(String s) {
   super(s);
 }

} class ImageNotFoundException extends Exception {

 ImageNotFoundException(ImageProducer source) {
   super(source + "");
 }

}



 </source>   



A rotating and scaling rectangle.

<source lang="java"> import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class SwingTimerBasedAnimationScaleRotate extends JPanel implements ActionListener {

 Timer timer;
 private double angle = 0;
 private double scale = 1;
 private double delta = 0.01;
 Rectangle.Float r = new Rectangle.Float(20, 20, 200, 200);
 public SwingTimerBasedAnimationScaleRotate() {
   timer = new Timer(10, this);
   timer.start();
 }
 public void paint(Graphics g) {
   int h = getHeight();
   int w = getWidth();
   Graphics2D g2d = (Graphics2D) g;
   g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
   g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
   g2d.translate(w / 2, h / 2);
   g2d.rotate(angle);
   g2d.scale(scale, scale);
   g2d.fill(r);
 }
 public static void main(String[] args) {
   JFrame frame = new JFrame("Moving star");
   frame.add(new SwingTimerBasedAnimationScaleRotate());
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setSize(420, 250);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }
 public void actionPerformed(ActionEvent e) {
   if (scale < 0.01) {
     delta = -delta;
   } else if (scale > 0.99) {
     delta = -delta;
   }
   scale += delta;
   angle += 0.01;
   repaint();
 }

}



 </source>   



A simple spring simulation in one dimension

<source lang="java"> /*

*  $Id: FloatSpring.java,v 1.4 2007/06/25 23:00:10 shingoki Exp $
*
*  Copyright (c) 2005-2006 shingoki
*
*  This file is part of AirCarrier, see http://aircarrier.dev.java.net/
*
*    AirCarrier is free software; you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation; either version 2 of the License, or
*    (at your option) any later version.
*    AirCarrier is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*    You should have received a copy of the GNU General Public License
*    along with AirCarrier; if not, write to the Free Software
*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*/

/**

* A simple spring simulation in one dimension Useful for getting a property
* (for example a position) to move from one value to another, in a smooth
* looking way. To use, create a spring with appropriate constants (e.g. new
* FloatSpring(100) is a reasonable value) Then set spring position to the
* initial value, and update each frame with target parameter as your desired
* value. The position parameter will "snap to" the desired value.
* 
* @author goki
*/

public class FloatSpring {

 float position;
 float springK;
 float dampingK;
 float velocity;
 /**
  * Make a spring with given spring constant and damping constant
  * 
  * @param springK
  *          Spring constant, the higher this is the "tighter" the spring, and
  *          the more force it will exert for a given extension
  * @param dampingK
  *          Damping constant, the higher this is the stronger the damping, and
  *          the more "soggy" the movement.
  */
 public FloatSpring(float springK, float dampingK) {
   super();
   this.position = 0;
   this.springK = springK;
   this.dampingK = dampingK;
   this.velocity = 0;
 }
 /**
  * Create a critically damped spring (or near to critically damped) This
  * spring will quickly move to its target without overshooting
  * 
  * @param springK
  *          The spring constant - the higher this is, the more quickly the
  *          spring will reach its target. A value of 100 gives a reasonable
  *          response in about a second, a higher value gives a faster
  *          response.
  */
 public FloatSpring(float springK) {
   this(springK, (float) (2 * Math.sqrt(springK)));
 }
 /**
  * Update the position of the spring. This updates the "position" as if there
  * were a damped spring stretched between the current position and the target
  * position. That is, the spring will tend to pull the position towards the
  * target, and if the spring is damped the position will eventually settle
  * onto the target.
  * 
  * @param target
  *          The target towards which the spring is pulling the position
  * @param time
  *          The elapsed time in seconds
  */
 public void update(float target, float time) {
   // Set v to target - position, this is the required movement
   float v = position - target;
   // Multiply displacement by spring constant to get spring force,
   // then subtract damping force
   v = v * -springK - velocity * dampingK;
   // v is now a force, so assuming unit mass is is also acceleration.
   // multiply by elapsed time to get velocity change
   velocity += v * time;
   // If velocity isn"t valid, zero it
   if (Float.isNaN(velocity) || Float.isInfinite(velocity)) {
     velocity = 0;
   }
   // Change the position at the new velocity, for elapsed time
   position += velocity * time;
 }
 /**
  * @return Damping constant, the higher this is the stronger the damping, and
  *         the more "soggy" the movement.
  */
 public float getDampingK() {
   return dampingK;
 }
 /**
  * @param dampingK
  *          Damping constant, the higher this is the stronger the damping, and
  *          the more "soggy" the movement.
  */
 public void setDampingK(float dampingK) {
   this.dampingK = dampingK;
 }
 /**
  * @return The current position of the simulated spring end point, changes as
  *         simulation is updated
  */
 public float getPosition() {
   return position;
 }
 /**
  * @param position
  *          A new position for simulated spring end point
  */
 public void setPosition(float position) {
   this.position = position;
 }
 /**
  * @return The spring constant - the higher this is, the more quickly the
  *         spring will reach its target
  */
 public float getSpringK() {
   return springK;
 }
 /**
  * @param springK
  *          The spring constant - the higher this is, the more quickly the
  *          spring will reach its target
  */
 public void setSpringK(float springK) {
   this.springK = springK;
 }
 /**
  * @return The current velocity of the position
  */
 public float getVelocity() {
   return velocity;
 }
 /**
  * @param velocity
  *          A new value for the current velocity of the position
  */
 public void setVelocity(float velocity) {
   this.velocity = velocity;
 }

}


 </source>   



Bouncing Circle

<source lang="java"> /*

* Copyright (c) 2000 David Flanagan.  All rights reserved.
* This code is from the book Java Examples in a Nutshell, 2nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book (recommended),
* visit http://www.davidflanagan.ru/javaexamples2.
*/

import java.applet.Applet; import java.awt.Color; import java.awt.Graphics; import java.awt.Rectangle; /** An applet that displays a simple animation */ public class BouncingCircle extends Applet implements Runnable {

 int x = 150, y = 50, r = 50; // Position and radius of the circle
 int dx = 11, dy = 7; // Trajectory of circle
 Thread animator; // The thread that performs the animation
 volatile boolean pleaseStop; // A flag to ask the thread to stop
 /** This method simply draws the circle at its current position */
 public void paint(Graphics g) {
   g.setColor(Color.red);
   g.fillOval(x - r, y - r, r * 2, r * 2);
 }
 /**
  * This method moves (and bounces) the circle and then requests a redraw.
  * The animator thread calls this method periodically.
  */
 public void animate() {
   // Bounce if we"ve hit an edge.
   Rectangle bounds = getBounds();
   if ((x - r + dx < 0) || (x + r + dx > bounds.width))
     dx = -dx;
   if ((y - r + dy < 0) || (y + r + dy > bounds.height))
     dy = -dy;
   // Move the circle.
   x += dx;
   y += dy;
   // Ask the browser to call our paint() method to draw the circle
   // at its new position.
   repaint();
 }
 /**
  * This method is from the Runnable interface. It is the body of the thread
  * that performs the animation. The thread itself is created and started in
  * the start() method.
  */
 public void run() {
   while (!pleaseStop) { // Loop until we"re asked to stop
     animate(); // Update and request redraw
     try {
       Thread.sleep(100);
     } // Wait 100 milliseconds
     catch (InterruptedException e) {
     } // Ignore interruptions
   }
 }
 /** Start animating when the browser starts the applet */
 public void start() {
   animator = new Thread(this); // Create a thread
   pleaseStop = false; // Don"t ask it to stop now
   animator.start(); // Start the thread.
   // The thread that called start now returns to its caller.
   // Meanwhile, the new animator thread has called the run() method
 }
 /** Stop animating when the browser stops the applet */
 public void stop() {
   // Set the flag that causes the run() method to end
   pleaseStop = true;
 }

}



 </source>   



Buffered Animation Demo

<source lang="java"> import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; import java.awt.image.BufferedImage; import java.util.Timer; import java.util.TimerTask; import javax.swing.JFrame; public class BufferedAnimate extends JFrame {

 private static int DELAY = 100;
 Image buffer;
 Dimension oldSize;
 Insets insets;
 Color colors[] = { Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN,
     Color.BLUE, Color.MAGENTA };
 public void paint(Graphics g) {
   if ((oldSize == null) || (oldSize != getSize())) {
     oldSize = getSize();
     buffer = new BufferedImage(getWidth(), getHeight(),
         BufferedImage.TYPE_INT_RGB);
   }
   if (insets == null) {
     insets = getInsets();
   }
   // Calculate each time in case of resize
   int x = insets.left;
   int y = insets.top;
   int width = getWidth() - insets.left - insets.right;
   int height = getHeight() - insets.top - insets.bottom;
   int start = 0;
   int steps = colors.length;
   int stepSize = 360 / steps;
   synchronized (colors) {
     Graphics bufferG = buffer.getGraphics();
     bufferG.setColor(Color.WHITE);
     bufferG.fillRect(x, y, width, height);
     for (int i = 0; i < steps; i++) {
       bufferG.setColor(colors[i]);
       bufferG.fillArc(x, y, width, height, start, stepSize);
       start += stepSize;
     }
   }
   g.drawImage(buffer, 0, 0, this);
 }
 public void go() {
   TimerTask task = new TimerTask() {
     public void run() {
       Color c = colors[0];
       synchronized (colors) {
         System.arraycopy(colors, 1, colors, 0, colors.length - 1);
         colors[colors.length - 1] = c;
       }
       repaint();
     }
   };
   Timer timer = new Timer();
   timer.schedule(task, 0, DELAY);
 }
 public static void main(String args[]) {
   BufferedAnimate f = new BufferedAnimate();
   f.setSize(200, 200);
   f.setTitle("Buffered");
   f.show();
   f.go();
 }

}




 </source>   



Composition technique in this animation.

<source lang="java"> import java.awt.AlphaComposite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class ImageComposite extends JPanel implements ActionListener {

 Image a = new ImageIcon(this.getClass().getResource("a.png")).getImage();
 Image b = new ImageIcon(this.getClass().getResource("b.png")).getImage();
 Timer timer = new Timer(800, this);
 float alpha = 1f;
 public ImageComposite() {
   timer.start();
 }
 public void paint(Graphics g) {
   super.paint(g);
   Graphics2D g2d = (Graphics2D) g;
   BufferedImage buffImg = new BufferedImage(200, 100, BufferedImage.TYPE_INT_ARGB);
   Graphics2D gbi = buffImg.createGraphics();
   AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
   gbi.drawImage(a, 40, 30, null);
   gbi.setComposite(ac);
   gbi.drawImage(b, 0, 0, null);
   g2d.drawImage(buffImg, 20, 20, null);
 }
 public void actionPerformed(ActionEvent e) {
   alpha -= 0.1;
   if (alpha <= 0) {
     alpha = 0;
     timer.stop();
   }
   repaint();
 }
 public static void main(String[] args) {
   JFrame frame = new JFrame();
   frame.add(new ImageComposite());
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setSize(300, 210);
   frame.setVisible(true);
 }

}



 </source>   



Fade out an image: image gradually get more transparent until it is completely invisible.

<source lang="java">

import java.awt.AlphaComposite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class FadeOutImage extends JPanel implements ActionListener {

 Image myImage = new ImageIcon("a.jpg").getImage();
 Timer timer = new Timer(20, this);
 private float alpha = 1f;
 public FadeOutImage() {
   timer.start();
 }
 public void paint(Graphics g) {
   super.paint(g);
   Graphics2D g2d = (Graphics2D) g;
   g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
   g2d.drawImage(myImage, 10, 10, null);
 }
 public void actionPerformed(ActionEvent e) {
   alpha += -0.01f;
   if (alpha <= 0) {
     alpha = 0;
     timer.stop();
   }
   repaint();
 }
 public static void main(String[] args) {
   JFrame frame = new JFrame("Fade out");
   frame.add(new FadeOutImage());
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setSize(300, 250);
   frame.setVisible(true);
 }

}



 </source>   



Font size animation

<source lang="java"> import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class FontSizeAnimation extends JPanel implements ActionListener {

 Timer timer;
 int x = 1;
 float alpha = 1;
 public FontSizeAnimation() {
   timer = new Timer(8, this);
   timer.setInitialDelay(190);
   timer.start();
 }
 public void paint(Graphics g) {
   super.paintComponent(g);
   Graphics2D g2d = (Graphics2D) g;
   Font font = new Font("Dialog", Font.PLAIN, x);
   g2d.setFont(font);
   FontMetrics fm = g2d.getFontMetrics();
   String s = "Java";
   
   int w = (int) getSize().getWidth();
   int h = (int) getSize().getHeight();
   int stringWidth = fm.stringWidth(s);
   g2d.drawString(s, (w - stringWidth) / 2, h / 2);
 }
 public static void main(String[] args) {
   JFrame frame = new JFrame("FontSizeAnimation");
   frame.add(new FontSizeAnimation());
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setSize(400, 300);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }
 public void actionPerformed(ActionEvent e) {
   x += 1;
   alpha -= 0.0001;
   repaint();
 }

}



 </source>   



How to create animation

<source lang="java"> import java.applet.Applet; import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; public class AppletAnimation extends Applet implements Runnable {

 int frameNumber = -1;
 int delay = 100;
 Thread animatorThread;
 boolean frozen = false;
 public void init() {
   String str;
   addMouseListener(new MouseAdapter() {
     public void mousePressed(MouseEvent e) {
       if (frozen) {
         frozen = false;
         start();
       } else {
         frozen = true;
         stop();
       }
     }
   });
 }
 public void start() {
   if (!frozen) {
     if (animatorThread == null) {
       animatorThread = new Thread(this);
     }
     animatorThread.start();
   }
 }
 public void stop() {
   animatorThread = null;
 }
 public void run() {
   Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
   long startTime = System.currentTimeMillis();
   Thread currentThread = Thread.currentThread();
   while (currentThread == animatorThread) {
     frameNumber++;
     repaint();
     try {
       startTime += delay;
       Thread.sleep(100);
     } catch (InterruptedException e) {
       break;
     }
   }
 }
 public void paint(Graphics g) {
   g.drawString("Frame " + frameNumber, 0, 30);
 }

}



 </source>   



How to create Animation: Paint and thread

<source lang="java"> import java.awt.Color; import java.awt.Graphics; import java.awt.Insets; import java.util.Timer; import java.util.TimerTask; import javax.swing.JFrame; public class Animate extends JFrame {

 private static int DELAY = 100;
 Insets insets;
 Color colors[] = { Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN,
     Color.BLUE, Color.MAGENTA };
 public void paint(Graphics g) {
   super.paint(g);
   if (insets == null) {
     insets = getInsets();
   }
   // Calculate each time in case of resize
   int x = insets.left;
   int y = insets.top;
   int width = getWidth() - insets.left - insets.right;
   int height = getHeight() - insets.top - insets.bottom;
   int start = 0;
   int steps = colors.length;
   int stepSize = 360 / steps;
   synchronized (colors) {
     for (int i = 0; i < steps; i++) {
       g.setColor(colors[i]);
       g.fillArc(x, y, width, height, start, stepSize);
       start += stepSize;
     }
   }
 }
 public void go() {
   TimerTask task = new TimerTask() {
     public void run() {
       Color c = colors[0];
       synchronized (colors) {
         System.arraycopy(colors, 1, colors, 0, colors.length - 1);
         colors[colors.length - 1] = c;
       }
       repaint();
     }
   };
   Timer timer = new Timer();
   timer.schedule(task, 0, DELAY);
 }
 public static void main(String args[]) {
   Animate f = new Animate();
   f.setSize(200, 200);
   f.show();
   f.go();
 }

}



 </source>   



Hypnosis animation

<source lang="java"> import java.awt.Color; import java.awt.Dimension; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Paint; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.geom.GeneralPath; import javax.swing.JComponent; import javax.swing.JFrame; public class Hypnosis1 extends JComponent implements Runnable {

 private int[] coordinates;
 private int[] deltas;
 private Paint paint;
 public Hypnosis1(int numberOfSegments) {
   int numberOfCoordinates = numberOfSegments * 4 + 2;
   coordinates = new int[numberOfCoordinates];
   deltas = new int[numberOfCoordinates];
   for (int i = 0; i < numberOfCoordinates; i++) {
     coordinates[i] = (int) (Math.random() * 300);
     deltas[i] = (int) (Math.random() * 4 + 3);
     if (deltas[i] > 4)
       deltas[i] = -(deltas[i] - 3);
   }
   paint = new GradientPaint(0, 0, Color.blue, 20, 10, Color.red, true);
   Thread t = new Thread(this);
   t.start();
 }
 public void run() {
   try {
     while (true) {
       timeStep();
       repaint();
       Thread.sleep(1000 / 24);
     }
   } catch (InterruptedException ie) {
   }
 }
 public void paint(Graphics g) {
   Graphics2D g2 = (Graphics2D) g;
   g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
   Shape s = createShape();
   g2.setPaint(paint);
   g2.fill(s);
   g2.setPaint(Color.white);
   g2.draw(s);
 }
 private void timeStep() {
   Dimension d = getSize();
   if (d.width == 0 || d.height == 0)
     return;
   for (int i = 0; i < coordinates.length; i++) {
     coordinates[i] += deltas[i];
     int limit = (i % 2 == 0) ? d.width : d.height;
     if (coordinates[i] < 0) {
       coordinates[i] = 0;
       deltas[i] = -deltas[i];
     } else if (coordinates[i] > limit) {
       coordinates[i] = limit - 1;
       deltas[i] = -deltas[i];
     }
   }
 }
 private Shape createShape() {
   GeneralPath path = new GeneralPath();
   path.moveTo(coordinates[0], coordinates[1]);
   for (int i = 2; i < coordinates.length; i += 4)
     path.quadTo(coordinates[i], coordinates[i + 1], coordinates[i + 2], coordinates[i + 3]);
   path.closePath();
   return path;
 }
 public static void main(String[] args) {
   JFrame f = new JFrame("Hypnosis");
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.add(new Hypnosis1(4));
   f.setSize(300, 300);
   f.setVisible(true);
 }

}



 </source>   



Image Bouncer

<source lang="java"> import java.awt.BorderLayout; import java.awt.Checkbox; import java.awt.Choice; import java.awt.ruponent; import java.awt.Dimension; import java.awt.Font; import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Label; import java.awt.MediaTracker; import java.awt.Panel; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.event.ruponentAdapter; import java.awt.event.ruponentEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.net.MalformedURLException; import java.net.URL; import java.text.NumberFormat; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; public class ImageBouncer extends JPanel implements Runnable {

 private boolean trucking = true;
 private long[] previousTimes; // milliseconds
 private int previousIndex;
 private boolean previousFilled;
 private double frameRate; // frames per second
 public static void main(String[] args) {
   String filename = "jexpLogo.png";
   if (args.length > 0)
     filename = args[0];
   Image image = null;
   try {
     image = blockingLoad(new URL(filename));
   } catch (MalformedURLException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
   }
   final ImageBouncer bouncer = new ImageBouncer(image);
   Frame f = new AnimationFrame(bouncer);
   f.setFont(new Font("Serif", Font.PLAIN, 12));
   Panel controls = new Panel();
   controls.add(bouncer.createCheckbox("Bilinear", ImageBouncer.BILINEAR));
   controls.add(bouncer.createCheckbox("Transform", ImageBouncer.TRANSFORM));
   final Choice typeChoice = new Choice();
   typeChoice.add("TYPE_INT_RGB");
   typeChoice.add("TYPE_INT_ARGB");
   typeChoice.add("TYPE_INT_ARGB_PRE");
   typeChoice.add("TYPE_3BYTE_BGR");
   typeChoice.add("TYPE_BYTE_GRAY");
   typeChoice.add("TYPE_USHORT_GRAY");
   typeChoice.add("TYPE_USHORT_555_RGB");
   typeChoice.add("TYPE_USHORT_565_RGB");
   controls.add(typeChoice);
   f.add(controls, BorderLayout.NORTH);
   typeChoice.addItemListener(new ItemListener() {
     public void itemStateChanged(ItemEvent ie) {
       String type = typeChoice.getSelectedItem();
       bouncer.setImageType(type);
     }
   });

f.setSize(200,200);

   f.setVisible(true);
 }
 private boolean mBilinear = false;
 private boolean mTransform = false;
 public static final int BILINEAR = 1;
 public static final int TRANSFORM = 3;
 private float mDeltaX, mDeltaY;
 private float mX, mY, mWidth, mHeight;
 private float mTheta;
 private Image mOriginalImage;
 private Image image;
 public ImageBouncer(Image image) {
   previousTimes = new long[128];
   previousTimes[0] = System.currentTimeMillis();
   previousIndex = 1;
   previousFilled = false;
 
   mOriginalImage = image;
   setImageType("TYPE_INT_RGB");
   Random random = new Random();
   mX = random.nextFloat() * 500;
   mY = random.nextFloat() * 500;
   mWidth = image.getWidth(this);
   mHeight = image.getHeight(this);
   mDeltaX = random.nextFloat() * 3;
   mDeltaY = random.nextFloat() * 3;
   // Make sure points are within range.
   addComponentListener(new ComponentAdapter() {
     public void componentResized(ComponentEvent ce) {
       Dimension d = getSize();
       if (mX < 0)
         mX = 0;
       else if (mX + mWidth >= d.width)
         mX = d.width - mWidth - 1;
       if (mY < 0)
         mY = 0;
       else if (mY + mHeight >= d.height)
         mY = d.height - mHeight - 1;
     }
   });
 }
 public void setSwitch(int item, boolean value) {
   switch (item) {
   case BILINEAR:
     mBilinear = value;
     break;
   case TRANSFORM:
     mTransform = value;
     break;
   default:
     break;
   }
 }
 public void setImageType(String s) {
   int type = BufferedImage.TYPE_CUSTOM;
   if (s.equals("TYPE_INT_RGB"))
     type = BufferedImage.TYPE_INT_RGB;
   else if (s.equals("TYPE_INT_ARGB"))
     type = BufferedImage.TYPE_INT_ARGB;
   else if (s.equals("TYPE_INT_ARGB_PRE"))
     type = BufferedImage.TYPE_INT_ARGB_PRE;
   else if (s.equals("TYPE_3BYTE_BGR"))
     type = BufferedImage.TYPE_3BYTE_BGR;
   else if (s.equals("TYPE_BYTE_GRAY"))
     type = BufferedImage.TYPE_BYTE_GRAY;
   else if (s.equals("TYPE_USHORT_GRAY"))
     type = BufferedImage.TYPE_USHORT_GRAY;
   else if (s.equals("TYPE_USHORT_555_RGB"))
     type = BufferedImage.TYPE_USHORT_565_RGB;
   else if (s.equals("TYPE_USHORT_565_RGB"))
     type = BufferedImage.TYPE_USHORT_565_RGB;
   else {
     System.out.println("Unrecognized type.");
     return;
   }
   image = makeBufferedImage(mOriginalImage, type);
 }
 protected Checkbox createCheckbox(String label, final int item) {
   Checkbox check = new Checkbox(label);
   check.addItemListener(new ItemListener() {
     public void itemStateChanged(ItemEvent ie) {
       setSwitch(item, (ie.getStateChange() == ie.SELECTED));
     }
   });
   return check;
 }
 public void timeStep() {
   Dimension d = getSize();
   if (mX + mDeltaX < 0)
     mDeltaX = -mDeltaX;
   else if (mX + mWidth + mDeltaX >= d.width)
     mDeltaX = -mDeltaX;
   if (mY + mDeltaY < 0)
     mDeltaY = -mDeltaY;
   else if (mY + mHeight + mDeltaY >= d.height)
     mDeltaY = -mDeltaY;
   mX += mDeltaX;
   mY += mDeltaY;
   mTheta += Math.PI / 192;
   if (mTheta > (2 * Math.PI))
     mTheta -= (2 * Math.PI);
 }
 public void paint(Graphics g) {
   Graphics2D g2 = (Graphics2D) g;
   setTransform(g2);
   setBilinear(g2);
   // Draw the image.
   g2
       .drawImage(image,
           AffineTransform.getTranslateInstance(mX, mY), null);
 }
 protected void setTransform(Graphics2D g2) {
   if (mTransform == false)
     return;
   float cx = mX + mWidth / 2;
   float cy = mY + mHeight / 2;
   g2.rotate(mTheta, cx, cy);
 }
 protected void setBilinear(Graphics2D g2) {
   if (mBilinear == false)
     return;
   g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
       RenderingHints.VALUE_INTERPOLATION_BILINEAR);
 }
 public void run() {
   while (trucking) {
     render();
     timeStep();
     calculateFrameRate();
   }
 }
 protected void render() {
   Graphics g = getGraphics();
   if (g != null) {
     Dimension d = getSize();
     if (checkImage(d)) {
       Graphics imageGraphics = image.getGraphics();
       // Clear the image background.
       imageGraphics.setColor(getBackground());
       imageGraphics.fillRect(0, 0, d.width, d.height);
       imageGraphics.setColor(getForeground());
       // Draw this component offscreen.
       paint(imageGraphics);
       // Now put the offscreen image on the screen.
       g.drawImage(image, 0, 0, null);
       // Clean up.
       imageGraphics.dispose();
     }
     g.dispose();
   }
 }
 // Offscreen image.
 protected boolean checkImage(Dimension d) {
   if (d.width == 0 || d.height == 0)
     return false;
   if (image == null || image.getWidth(null) != d.width
       || image.getHeight(null) != d.height) {
     image = createImage(d.width, d.height);
   }
   return true;
 }
 protected void calculateFrameRate() {
   // Measure the frame rate
   long now = System.currentTimeMillis();
   int numberOfFrames = previousTimes.length;
   double newRate;
   // Use the more stable method if a history is available.
   if (previousFilled)
     newRate = (double) numberOfFrames
         / (double) (now - previousTimes[previousIndex]) * 1000.0;
   else
     newRate = 1000.0 / (double) (now - previousTimes[numberOfFrames - 1]);
   firePropertyChange("frameRate", frameRate, newRate);
   frameRate = newRate;
   // Update the history.
   previousTimes[previousIndex] = now;
   previousIndex++;
   if (previousIndex >= numberOfFrames) {
     previousIndex = 0;
     previousFilled = true;
   }
 }
 public double getFrameRate() {
   return frameRate;
 }
 // Property change support.
 private transient AnimationFrame mRateListener;
 public void setRateListener(AnimationFrame af) {
   mRateListener = af;
 }
 public void firePropertyChange(String name, double oldValue, double newValue) {
   mRateListener.rateChanged(newValue);
 }
 private static Component sComponent = new Component() {
 };
 private static final MediaTracker sTracker = new MediaTracker(sComponent);
 private static int sID = 0;
 public static boolean waitForImage(Image image) {
   int id;
   synchronized (sComponent) {
     id = sID++;
   }
   sTracker.addImage(image, id);
   try {
     sTracker.waitForID(id);
   } catch (InterruptedException ie) {
     return false;
   }
   if (sTracker.isErrorID(id))
     return false;
   return true;
 }
 public Image blockingLoad(String path) {
   Image image = Toolkit.getDefaultToolkit().getImage(path);
   if (waitForImage(image) == false)
     return null;
   return image;
 }
 public static Image blockingLoad(URL url) {
   Image image = Toolkit.getDefaultToolkit().getImage(url);
   if (waitForImage(image) == false)
     return null;
   return image;
 }
 public BufferedImage makeBufferedImage(Image image) {
   return makeBufferedImage(image, BufferedImage.TYPE_INT_RGB);
 }
 public BufferedImage makeBufferedImage(Image image, int imageType) {
   if (waitForImage(image) == false)
     return null;
   BufferedImage bufferedImage = new BufferedImage(image.getWidth(null),
       image.getHeight(null), imageType);
   Graphics2D g2 = bufferedImage.createGraphics();
   g2.drawImage(image, null, null);
   return bufferedImage;
 }

} class AnimationFrame extends JFrame {

 private Label mStatusLabel;
 private NumberFormat mFormat;
 public AnimationFrame(ImageBouncer ac) {
   super();
   setLayout(new BorderLayout());
   add(ac, BorderLayout.CENTER);
   add(mStatusLabel = new Label(), BorderLayout.SOUTH);
   // Create a number formatter.
   mFormat = NumberFormat.getInstance();
   mFormat.setMaximumFractionDigits(1);
   // Listen for the frame rate changes.
   ac.setRateListener(this);
   // Kick off the animation.
   Thread t = new Thread(ac);
   t.start();
 }
 public void rateChanged(double frameRate) {
   mStatusLabel.setText(mFormat.format(frameRate) + " fps");
 }

}




 </source>   



Is Event Dispatcher Thread

<source lang="java"> import java.awt.Color; import java.awt.ruponent; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Random; import javax.swing.AbstractAction; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JTable; import javax.swing.SwingUtilities; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; public class IsEDTExample extends JPanel {

 private boolean keepRunning;
 private static int RED = 0;
 private static int BLUE = 1;
 private static int GREEN = 2;
 private static int VARIABLE = 3;
 private static int SIZE = 3;
 private int threadShade;
 private ColorTableModel tableModel= new ColorTableModel();
 private Thread colorShadeThread;
 public IsEDTExample() {
   JTable table = new JTable(tableModel);
   table.setRowHeight(100);
   table.setDefaultRenderer(Object.class, new ColorRenderer());
   add(table);
   add(new JLabel("Thread Color Shade:"));
   ButtonGroup group = new ButtonGroup();
   JRadioButton redOption = new JRadioButton("Red");
   group.add(redOption);
   redOption.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       threadShade = RED;
     }
   });
   JRadioButton blueOption = new JRadioButton("Blue");
   group.add(blueOption);
   blueOption.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       threadShade = BLUE;
     }
   });
   JRadioButton greenOption = new JRadioButton("Green");
   group.add(greenOption);
   greenOption.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
       threadShade = GREEN;
     }
   });
   redOption.setSelected(true);
   this.threadShade = RED;
   add(redOption);
   add(greenOption);
   add(blueOption);
   add(new JButton(new RandomColorAction()));
   this.keepRunning = true;
   this.colorShadeThread = new Thread(new RandomColorShadeRunnable());
   this.colorShadeThread.start();
 }
 private class RandomColorAction extends AbstractAction {
   public RandomColorAction() {
     super("Create Random Color");
   }
   public void actionPerformed(ActionEvent e) {
     IsEDTExample.this.tableModel.generateRandomColor(VARIABLE);
   }
 }
 private class ColorTableModel extends AbstractTableModel {
   private Color[][] colors = new Color[3][3];
   public ColorTableModel() {
     for (int i = 0; i < SIZE; i++) {
       for (int x = 0; x < SIZE; x++) {
         colors[i][x] = Color.white;
       }
     }
   }
   public int getRowCount() {
     return SIZE;
   }
   public int getColumnCount() {
     return SIZE;
   }
   public Object getValueAt(int rowIndex, int columnIndex) {
     return colors[rowIndex][columnIndex];
   }
   public void generateRandomColor(int type) {
     Random random = new Random(System.currentTimeMillis());
     final int row = random.nextInt(SIZE);
     final int column = random.nextInt(SIZE);
     final Color color;
     if (type == RED) {
       color = new Color(random.nextInt(256), 0, 0);
     } else if (type == BLUE) {
       color = new Color(0, 0, random.nextInt(256));
     } else if (type == GREEN) {
       color = new Color(0, random.nextInt(256), 0);
     } else {
       color = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
     }
     if (SwingUtilities.isEventDispatchThread()) {
       colors[row][column] = color;
       fireTableCellUpdated(row, column);
     } else {
       SwingUtilities.invokeLater(new Runnable() {
         public void run() {
           colors[row][column] = color;
           fireTableCellUpdated(row, column);
         }
       });
     }
   }
 }
 private class ColorRenderer implements TableCellRenderer {
   private JLabel label;
   public ColorRenderer() {
     label = new JLabel();
     label.setOpaque(true);
     label.setPreferredSize(new Dimension(100, 100));
   }
   public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
       boolean hasFocus, int row, int column) {
     label.setBackground((Color) value);
     return label;
   }
 }
 private class RandomColorShadeRunnable implements Runnable {
   public void run() {
     while (keepRunning) {
       tableModel.generateRandomColor(threadShade);
       try {
         Thread.sleep(500);
       } catch (InterruptedException e) {
       }
     }
   }
 }
 public static void main(String[] a) {
   JFrame f = new JFrame("Is Event Dispatch Thread Example");
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.add(new IsEDTExample());
   f.pack();
   f.setVisible(true);
 }

}



 </source>   



Make your own animation from a series of images

<source lang="java"> import java.awt.BorderLayout; import java.awt.Graphics; import java.awt.MediaTracker; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class Main extends JPanel implements ActionListener {

 ImageIcon images[];
 int totalImages = 30, currentImage = 0, animationDelay = 50;
 Timer animationTimer;
 public Main() {
   images = new ImageIcon[totalImages];
   for (int i = 0; i < images.length; ++i)
     images[i] = new ImageIcon("images/java" + i + ".gif");
   startAnimation();
 }
 public void paintComponent(Graphics g) {
   super.paintComponent(g);
   if (images[currentImage].getImageLoadStatus() == MediaTracker.ruPLETE) {
     images[currentImage].paintIcon(this, g, 0, 0);
     currentImage = (currentImage + 1) % totalImages;
   }
 }
 public void actionPerformed(ActionEvent e) {
   repaint();
 }
 public void startAnimation() {
   if (animationTimer == null) {
     currentImage = 0;
     animationTimer = new Timer(animationDelay, this);
     animationTimer.start();
   } else if (!animationTimer.isRunning())
     animationTimer.restart();
 }
 public void stopAnimation() {
   animationTimer.stop();
 }
 public static void main(String args[]) {
   Main anim = new Main();
   JFrame app = new JFrame("Animator test");
   app.add(anim, BorderLayout.CENTER);
   app.setSize(300,300);
   app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   app.setSize(anim.getPreferredSize().width + 10, anim.getPreferredSize().height + 30);
 }

}



 </source>   



Noise Image

<source lang="java"> import java.awt.Graphics; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.IndexColorModel; import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.util.Random; import javax.swing.JComponent; import javax.swing.JFrame; public class StaticGenerator extends JComponent implements Runnable {

 byte[] data;
 BufferedImage image;
 Random random;
 public void initialize() {
   int w = getSize().width, h = getSize().height;
   int length = ((w + 7) * h) / 8;
   data = new byte[length];
   DataBuffer db = new DataBufferByte(data, length);
   WritableRaster wr = Raster.createPackedRaster(db, w, h, 1, null);
   ColorModel cm = new IndexColorModel(1, 2, new byte[] { (byte) 0, (byte) 255 }, new byte[] {
       (byte) 0, (byte) 255 }, new byte[] { (byte) 0, (byte) 255 });
   image = new BufferedImage(cm, wr, false, null);
   random = new Random();
   new Thread(this).start();
 }
 public void run() {
   while (true) {
     random.nextBytes(data);
     repaint();
     try {
       Thread.sleep(1000 / 24);
     } catch (InterruptedException e) { /* die */
     }
   }
 }
 public void paint(Graphics g) {
   if (image == null)
     initialize();
   g.drawImage(image, 0, 0, this);
 }
 public static void main(String[] args) {
   JFrame f = new JFrame();
   f.add(new StaticGenerator());
   f.setSize(300, 300);
   f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   f.setVisible(true);
 }

}



 </source>   



Text animation

<source lang="java"> import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Checkbox; import java.awt.Choice; import java.awt.Color; import java.awt.ruponent; import java.awt.Dimension; import java.awt.Font; import java.awt.Frame; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsEnvironment; import java.awt.GridLayout; import java.awt.Image; import java.awt.Label; import java.awt.MediaTracker; import java.awt.Panel; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.event.ruponentAdapter; import java.awt.event.ruponentEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.net.URL; import java.text.NumberFormat; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; public class TextBouncer extends JPanel implements Runnable {

 private boolean trucking = true;
 private long[] previousTimes; // milliseconds
 private int previousIndex;
 private boolean previousFilled;
 private double frameRate; // frames per second
 private Image image = null;
 public static void main(String[] args) {
   
   String s = "Java Source and Support";
   final int size = 64;
   if (args.length > 0)
     s = args[0];
   Panel controls = new Panel();
   final Choice choice = new Choice();
   GraphicsEnvironment ge = GraphicsEnvironment
       .getLocalGraphicsEnvironment();
   Font[] allFonts = ge.getAllFonts();
   for (int i = 0; i < allFonts.length; i++)
     choice.addItem(allFonts[i].getName());
   Font defaultFont = new Font(allFonts[0].getName(), Font.PLAIN, size);
   final TextBouncer bouncer = new TextBouncer(s, defaultFont);
   Frame f = new AnimationFrame(bouncer);
   f.setFont(new Font("Serif", Font.PLAIN, 12));
   controls.add(bouncer.createCheckbox("Antialiasing",
       TextBouncer.ANTIALIASING));
   controls.add(bouncer.createCheckbox("Gradient", TextBouncer.GRADIENT));
   controls.add(bouncer.createCheckbox("Shear", TextBouncer.SHEAR));
   controls.add(bouncer.createCheckbox("Rotate", TextBouncer.ROTATE));
   controls.add(bouncer.createCheckbox("Axes", TextBouncer.AXES));
   Panel fontControls = new Panel();
   choice.addItemListener(new ItemListener() {
     public void itemStateChanged(ItemEvent ie) {
       Font font = new Font(choice.getSelectedItem(), Font.PLAIN, size);
       bouncer.setFont(font);
     }
   });
   fontControls.add(choice);
   Panel allControls = new Panel(new GridLayout(2, 1));
   allControls.add(controls);
   allControls.add(fontControls);
   f.add(allControls, BorderLayout.NORTH);
       f.setSize(300,300);
   f.setVisible(true);
 }
 private boolean mAntialiasing = false, mGradient = false;
 private boolean mShear = false, mRotate = false, mAxes = false;
 public static final int ANTIALIASING = 0;
 public static final int GRADIENT = 1;
 public static final int SHEAR = 2;
 public static final int ROTATE = 3;
 public static final int AXES = 5;
 private float mDeltaX, mDeltaY;
 private float mX, mY, mWidth, mHeight;
 private float mTheta;
 private float mShearX, mShearY, mShearDeltaX, mShearDeltaY;
 private String mString;
 public TextBouncer(String s, Font f) {
   previousTimes = new long[128];
   previousTimes[0] = System.currentTimeMillis();
   previousIndex = 1;
   previousFilled = false;
   
   mString = s;
   setFont(f);
   Random random = new Random();
   mX = random.nextFloat() * 500;
   mY = random.nextFloat() * 500;
   mDeltaX = random.nextFloat() * 3;
   mDeltaY = random.nextFloat() * 3;
   mShearX = random.nextFloat() / 2;
   mShearY = random.nextFloat() / 2;
   mShearDeltaX = mShearDeltaY = .05f;
   FontRenderContext frc = new FontRenderContext(null, true, false);
   Rectangle2D bounds = getFont().getStringBounds(mString, frc);
   mWidth = (float) bounds.getWidth();
   mHeight = (float) bounds.getHeight();
   // Make sure points are within range.
   addComponentListener(new ComponentAdapter() {
     public void componentResized(ComponentEvent ce) {
       Dimension d = getSize();
       if (mX < 0)
         mX = 0;
       else if (mX + mWidth >= d.width)
         mX = d.width - mWidth - 1;
       if (mY < 0)
         mY = 0;
       else if (mY + mHeight >= d.height)
         mY = d.height - mHeight - 1;
     }
   });
 }
 public void setSwitch(int item, boolean value) {
   switch (item) {
   case ANTIALIASING:
     mAntialiasing = value;
     break;
   case GRADIENT:
     mGradient = value;
     break;
   case SHEAR:
     mShear = value;
     break;
   case ROTATE:
     mRotate = value;
     break;
   case AXES:
     mAxes = value;
     break;
   default:
     break;
   }
 }
 protected Checkbox createCheckbox(String label, final int item) {
   Checkbox check = new Checkbox(label);
   check.addItemListener(new ItemListener() {
     public void itemStateChanged(ItemEvent ie) {
       setSwitch(item, (ie.getStateChange() == ie.SELECTED));
     }
   });
   return check;
 }
 public void timeStep() {
   Dimension d = getSize();
   if (mX + mDeltaX < 0)
     mDeltaX = -mDeltaX;
   else if (mX + mWidth + mDeltaX >= d.width)
     mDeltaX = -mDeltaX;
   if (mY + mDeltaY < 0)
     mDeltaY = -mDeltaY;
   else if (mY + mHeight + mDeltaY >= d.height)
     mDeltaY = -mDeltaY;
   mX += mDeltaX;
   mY += mDeltaY;
   mTheta += Math.PI / 192;
   if (mTheta > (2 * Math.PI))
     mTheta -= (2 * Math.PI);
   if (mShearX + mShearDeltaX > .5)
     mShearDeltaX = -mShearDeltaX;
   else if (mShearX + mShearDeltaX < -.5)
     mShearDeltaX = -mShearDeltaX;
   if (mShearY + mShearDeltaY > .5)
     mShearDeltaY = -mShearDeltaY;
   else if (mShearY + mShearDeltaY < -.5)
     mShearDeltaY = -mShearDeltaY;
   mShearX += mShearDeltaX;
   mShearY += mShearDeltaY;
 }
 public void paint(Graphics g) {
   Graphics2D g2 = (Graphics2D) g;
   setAntialiasing(g2);
   setTransform(g2);
   setPaint(g2);
   // Draw the string.
   g2.setFont(getFont());
   g2.drawString(mString, mX, mY + mHeight);
   drawAxes(g2);
 }
 protected void setAntialiasing(Graphics2D g2) {
   if (mAntialiasing == false)
     return;
   g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
       RenderingHints.VALUE_ANTIALIAS_ON);
 }
 protected void setTransform(Graphics2D g2) {
   Dimension d = getSize();
   int cx = d.width / 2;
   int cy = d.height / 2;
   g2.translate(cx, cy);
   if (mShear)
     g2.shear(mShearX, mShearY);
   if (mRotate)
     g2.rotate(mTheta);
   g2.translate(-cx, -cy);
 }
 protected void setPaint(Graphics2D g2) {
   if (mGradient) {
     GradientPaint gp = new GradientPaint(0, 0, Color.blue, 50, 25,
         Color.green, true);
     g2.setPaint(gp);
   } else
     g2.setPaint(Color.orange);
 }
 protected void drawAxes(Graphics2D g2) {
   if (mAxes == false)
     return;
   g2.setPaint(getForeground());
   g2.setStroke(new BasicStroke());
   Dimension d = getSize();
   int side = 20;
   int arrow = 4;
   int w = d.width / 2, h = d.height / 2;
   g2.drawLine(w - side, h, w + side, h);
   g2.drawLine(w + side - arrow, h - arrow, w + side, h);
   g2.drawLine(w, h - side, w, h + side);
   g2.drawLine(w + arrow, h + side - arrow, w, h + side);
 }
 public void run() {
   while (trucking) {
     render();
     timeStep();
     calculateFrameRate();
   }
 }
 protected void render() {
   Graphics g = getGraphics();
   if (g != null) {
     Dimension d = getSize();
     if (checkImage(d)) {
       Graphics imageGraphics = image.getGraphics();
       // Clear the image background.
       imageGraphics.setColor(getBackground());
       imageGraphics.fillRect(0, 0, d.width, d.height);
       imageGraphics.setColor(getForeground());
       // Draw this component offscreen.
       paint(imageGraphics);
       // Now put the offscreen image on the screen.
       g.drawImage(image, 0, 0, null);
       // Clean up.
       imageGraphics.dispose();
     }
     g.dispose();
   }
 }
 // Offscreen image.
 protected boolean checkImage(Dimension d) {
   if (d.width == 0 || d.height == 0)
     return false;
   if (image == null || image.getWidth(null) != d.width
       || image.getHeight(null) != d.height) {
     image = createImage(d.width, d.height);
   }
   return true;
 }
 protected void calculateFrameRate() {
   // Measure the frame rate
   long now = System.currentTimeMillis();
   int numberOfFrames = previousTimes.length;
   double newRate;
   // Use the more stable method if a history is available.
   if (previousFilled)
     newRate = (double) numberOfFrames
         / (double) (now - previousTimes[previousIndex]) * 1000.0;
   else
     newRate = 1000.0 / (double) (now - previousTimes[numberOfFrames - 1]);
   firePropertyChange("frameRate", frameRate, newRate);
   frameRate = newRate;
   // Update the history.
   previousTimes[previousIndex] = now;
   previousIndex++;
   if (previousIndex >= numberOfFrames) {
     previousIndex = 0;
     previousFilled = true;
   }
 }
 public double getFrameRate() {
   return frameRate;
 }
 // Property change support.
 private transient AnimationFrame mRateListener;
 public void setRateListener(AnimationFrame af) {
   mRateListener = af;
 }
 public void firePropertyChange(String name, double oldValue, double newValue) {
   mRateListener.rateChanged(newValue);
 }
 private static Component sComponent = new Component() {
 };
 private static final MediaTracker sTracker = new MediaTracker(sComponent);
 private static int sID = 0;
 public static boolean waitForImage(Image image) {
   int id;
   synchronized (sComponent) {
     id = sID++;
   }
   sTracker.addImage(image, id);
   try {
     sTracker.waitForID(id);
   } catch (InterruptedException ie) {
     return false;
   }
   if (sTracker.isErrorID(id))
     return false;
   return true;
 }
 public Image blockingLoad(String path) {
   Image image = Toolkit.getDefaultToolkit().getImage(path);
   if (waitForImage(image) == false)
     return null;
   return image;
 }
 public static Image blockingLoad(URL url) {
   Image image = Toolkit.getDefaultToolkit().getImage(url);
   if (waitForImage(image) == false)
     return null;
   return image;
 }
 public BufferedImage makeBufferedImage(Image image) {
   return makeBufferedImage(image, BufferedImage.TYPE_INT_RGB);
 }
 public BufferedImage makeBufferedImage(Image image, int imageType) {
   if (waitForImage(image) == false)
     return null;
   BufferedImage bufferedImage = new BufferedImage(image.getWidth(null),
       image.getHeight(null), imageType);
   Graphics2D g2 = bufferedImage.createGraphics();
   g2.drawImage(image, null, null);
   return bufferedImage;
 }

} class AnimationFrame extends JFrame {

 private Label mStatusLabel;
 private NumberFormat mFormat;
 public AnimationFrame(TextBouncer ac) {
   super();
   setLayout(new BorderLayout());
   add(ac, BorderLayout.CENTER);
   add(mStatusLabel = new Label(), BorderLayout.SOUTH);
   // Create a number formatter.
   mFormat = NumberFormat.getInstance();
   mFormat.setMaximumFractionDigits(1);
   // Listen for the frame rate changes.
   ac.setRateListener(this);
   // Kick off the animation.
   Thread t = new Thread(ac);
   t.start();
 }
 public void rateChanged(double frameRate) {
   mStatusLabel.setText(mFormat.format(frameRate) + " fps");
 }

}




 </source>   



Timer based animation

<source lang="java"> import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.Ellipse2D; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class TimerBasedAnimation extends JPanel implements ActionListener {

 private Ellipse2D.Float ellipse = new Ellipse2D.Float();
 private double esize;
 private double maxSize = 0;
 private boolean initialize = true;
 Timer timer;
 ActionListener updateProBar;
 public TimerBasedAnimation() {
   setXY(20 * Math.random(), 200, 200);
   timer = new Timer(20, this);
   timer.setInitialDelay(190);
   timer.start();
 }
 public void setXY(double size, int w, int h) {
   esize = size;
   ellipse.setFrame(10, 10, size, size);
 }
 public void reset(int w, int h) {
   maxSize = w / 10;
   setXY(maxSize * Math.random(), w, h);
 }
 public void step(int w, int h) {
   esize++;
   if (esize > maxSize) {
     setXY(1, w, h);
   } else {
     ellipse.setFrame(ellipse.getX(), ellipse.getY(), esize, esize);
   }
 }
 public void render(int w, int h, Graphics2D g2) {
   g2.setColor(Color.BLUE);
   g2.draw(ellipse);
 }
 public void paint(Graphics g) {
   super.paintComponent(g);
   Graphics2D g2 = (Graphics2D) g;
   RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
       RenderingHints.VALUE_ANTIALIAS_ON);
   rh.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
   g2.setRenderingHints(rh);
   Dimension size = getSize();
   if (initialize) {
     reset(size.width, size.height);
     initialize = false;
   }
   this.step(size.width, size.height);
   render(size.width, size.height, g2);
 }
 public void actionPerformed(ActionEvent e) {
   repaint();
 }
 public static void main(String[] args) {
   JFrame frame = new JFrame("TimerBasedAnimation");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.add(new TimerBasedAnimation());
   frame.setSize(350, 250);
   frame.setLocationRelativeTo(null);
   frame.setVisible(true);
 }

}



 </source>   



Towers of Hanoi

<source lang="java"> import java.awt.*; import javax.swing.*; import no.geosoft.cc.graphics.*;

/**

* G demo program. Demonstrates:
*
*
    *
  • A sample game application *
  • Graphics animation *
  • GObject reparenting *
* 
* @author