Home arrow Java arrow Page 3 - Swing Animation
JAVA

Swing Animation


Have you ever been interested in creating a game using the Swing-based animation library? This article covers some important information to help you understand the backbone of this library. It is excerpted from the book Advanced Java Game Programming, written by David Wallace Croft (Apress, 2004; ISBN 1590591232).

Author Info:
By: Apress Publishing
Rating: 5 stars5 stars5 stars5 stars5 stars / 19
March 29, 2005
TABLE OF CONTENTS:
  1. · Swing Animation
  2. · RepaintCollector
  3. · SimpleRepaintCollector
  4. · CoalescingRepaintCollector
  5. · LoopGovernor
  6. · WindowedLoopGovernor
  7. · AnimatedComponent
  8. · Static method check()

print this article
SEARCH DEVARTICLES

Swing Animation - SimpleRepaintCollector
(Page 3 of 8 )

 public class   SimpleRepaintCollector
   implements RepaintCollector

SimpleRepaintCollector is a very simple concrete implementation of interface RepaintCollector. It exists in package com.croftsoft.core.animation.collector. The subpackage collector contains other concrete RepaintCollector implementations such as BooleanRepaintCollector, CoalescingRepaintCollector, NullRepaintCollector, and SwingRepaintCollector. I have organized the animation classes by grouping concrete implementations of an interface within a subpackage with the same name as the interface.

 private int       count;
 private Rectangle [ ]   repaintRegions;
 public SimpleRepaintCollector ( )
 ////////////////////////////////////////////////////////
 {
  repaintRegions = new Rectangle [ 0 ];
 }
 public int getCount ( ) { return count; }
 public Rectangle [ ] getRepaintRegions ( )
 ///////////////////////////////////////////////////////
 {
  return repaintRegions;
 }

SimpleRepaintCollector reacts to repaint requests by incrementing the request count and storing the request area. When its accessor methods are called, SimpleRepaintCollector simply returns the stored data as given.

  public void  repaint (
    int  x,
    int  y,
    int  width,
    int  height )
///////////////////////////////////////////////////////
  {
  if ( count == repaintRegions.length )
  {
   repaintRegions = ( Rectangle [ ] ) ArrayLib.append (
  repaintRegions, new Rectangle ( x, y, width, height ) );
  }
  else
  {
repaintRegions [ count ].setBounds ( x, y, width, height );
 }
count++;
}

A request to repaint an area is simply appended to the Rectangle array repaintRegions and the count is incremented. If the array is not long enough, it is replaced by a new array using the ArrayLib.append() method from package com.croftsoft.core.util. If the array is already long enough, an old Rectangle instance in the array is reused to hold the new data. Assuming the length of the array eventually stabilizes to some maximum value, probably equal to the number of sprites in the game, this technique ensures that new Rectangle instances do not need to be created with every animation loop.

This method is unsynchronized, as it is assumed that the repaint requests generated during the update phase will be serialized through the event dispatch thread. If this is not the case and this method is called simultaneously by more than one thread, the data could become garbled.

 public void repaint 
 )
 //////////////////////////////////////////////////////
 {
 repaint ( 0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE );
 }

The ArrayLib.append() method handles requests to repaint the entire component. The implementation simply delegates to the previous repaint() method using the maximum dimensions.

 public void reset ( )
 ///////////////////////////////////////////////////////
 {
    count = 0;
 }

The reset method simply resets the count to zero. The Rectangle array repaintRegions is not cleared, as the old data will simply be overwritten during the next loop.

BooleanRepaintCollector

BooleanRepaintCollector is another simple RepaintCollector implementation in that it simply repaints the entire component in response to one or more repaint requests, regardless of the sizes of the requested repaint areas. If there is no repaint request during the animation loop, no repaint will occur. Another way to think of this RepaintCollector implementation is as an all-or-nothing strategy that coalesces multiple requests into one.

The BooleanRepaintCollector is often adequate for many animation tasks. Since you know that this implementation is going to repaint the entire component with each frame if there is at least one repaint request, the Component-Animator implementations do not need to calculate the repaint areas when they perform the sprite position updates. This makes a lot of sense when the scene background is always moving around and you know that the entire component would have to be repainted anyway.

  private static final Rectangle [ ] REPAINT_REGIONS
    = new Rectangle [ ] {
  new Rectangle ( Integer.MAX_VALUE, Integer.MAX_VALUE ) };
 //
 private boolean  doRepaint;

Constant Rectangle array REPAINT_REGIONS contains a single rectangle of maximum size. Boolean doRepaint is a flag that indicates whether there has been a repaint request during the current animation-loop iteration.

  public int  getCount ( )
  /////////////////////////////////////////////////
  {
    return doRepaint ? 1 : 0;
  }
  public Rectangle [ ] getRepaintRegions ( )
  /////////////////////////////////////////////////
  {
    return REPAINT_REGIONS; }

The getCount() method simply returns a value of one if there have been any number of repaint requests whatsoever during the current animation-loop iteration. If the getCount() method returns zero instead, the array returned by method getRepaintRegions() will not be used, as only its first zero elements are assumed to contain valid data.

  public void  repaint (
    int  x,
    int  y,
    int  width,
    int  height )

  /////////////////////////////////////////////////////
  {
     doRepaint = true;
  }
  public void repaint ( )
  ///////////////////////////////////////////////////
  {
     doRepaint = true;
  }

These two methods simply set the doRepaint flag. Note that the area arguments in the first method are not used. If the sprites are not moving, neither of these methods will be called. In this case, the doRepaint flag will remain false.

  public void reset ( )
  ///////////////////////////////////////////////////
  {
    doRepaint = false;
  }

At the end of each animation loop iteration, the doRepaint flag is reset to false.

This article is excerpted from Advanced Java Game Programming by David Wallace Croft (Apress, 2004; ISBN 1590591232). Check it out at your favorite bookstore today. Buy this book now.


blog comments powered by Disqus
JAVA ARTICLES

- Java Too Insecure, Says Microsoft Researcher
- Google Beats Oracle in Java Ruling
- Deploying Multiple Java Applets as One
- Deploying Java Applets
- Understanding Deployment Frameworks
- Database Programming in Java Using JDBC
- Extension Interfaces and SAX
- Entities, Handlers and SAX
- Advanced SAX
- Conversions and Java Print Streams
- Formatters and Java Print Streams
- Java Print Streams
- Wildcards, Arrays, and Generics in Java
- Wildcards and Generic Methods in Java
- Finishing the Project: Java Web Development ...

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials