Mega Code Archive

 
Categories / Java / 2D Graphics GUI
 

Text animation

import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Checkbox; import java.awt.Choice; import java.awt.Color; import java.awt.Component; 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.ComponentAdapter; import java.awt.event.ComponentEvent; 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");   } }