Home arrow Java arrow Page 4 - 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 - CoalescingRepaintCollector
(Page 4 of 8 )

Using SimpleRepaintCollector can be inappropriate when you have requests to repaint small areas of the component, mixed with requests to repaint the entire component. In this case, you will end up repainting the small areas and then immediately repainting over them again in the same frame when you repaint the entire component one or more times. It would be better to use BooleanRepaint-Collector in this case to coalesce all of the repaint requests into one.

Using BooleanRepaintCollector, however, can be inappropriate when you only have requests to repaint a few small areas of the component. In this case you will repaint the entire component unnecessarily, which can slow the animation frame rate down. What is needed, then, is a strategy that is smart enough to behave like SimpleRepaintCollector when there are just a few small repaint areas, and like BooleanRepaintCollector when there is at least one request to repaint the entire component.

At the beginning of each animation loop iteration, CoalescingRepaint-Collector stores the repaint requests individually. If it receives a request to repaint the entire component, however, it will collapse the multiple individual requests into a single request. This makes CoalescingRepaintCollector a good implementation to use when it is not known beforehand whether the Component-Animator will make a request to repaint the entire component during every animation loop iteration.

  package com.croftsoft.core.animation.collector;
  import java.awt.Rectangle;
  import java.awt.geom.Rectangle2D;
  import com.croftsoft.core.animation.RepaintCollector;
  import com.croftsoft.core.util.ArrayLib;
  public class CoalescingRepaintCollector
    implements RepaintCollector
  ////////////////////////////////////////////////////
  ///////////////////////////////////////////////////
  {
  private static final Rectangle [ ] ALL_REGIONS = new
  Rectangle [ ] { new Rectangle ( Integer.MAX_VALUE, 
  Integer.MAX_VALUE ) };
  //
  private int           count;
  private boolean       repaintAll;
  private Rectangle [ ] repaintRegions
  //////////////////////////////////////////////////
  /////////////////////////////////////////////////
  public CoalescingRepaintCollector( )
  ////////////////////////////////////////////////
  {
   repaintRegions = new Rectangle [ 0 ];
  }

Boolean repaintAll is the flag that indicates whether the entire component should be repainted during this animation loop iteration. As you can see,

CoalescingRepaintCollector has most of the same instance variables as both SimpleRepaintCollector and BooleanRepaintCollector.

 public int getCount ( )
 //////////////////////////////////////////////////
 {
   if ( repaintAll )
 {
  return 1;
 }
 boolean  hasIntersections = true;
 while ( hasIntersections )
 {
   hasIntersections = false;
   iLoop:
   for ( int i = 0; i < count - 1; i++ )
   {
     Rectangle iRectangle = repaintRegions [ i ];
     for ( int j = i + 1; j < count; j++ )
     {
      Rectangle jRectangle = repaintRegions [ j ];
      if ( iRectangle.intersects ( jRectangle ) )
      {
       hasIntersections = true;
       Rectangle2D.union ( iRectangle, jRectangle, 
       iRectangle );
       repaintRegions [ j ] = repaintRegions [ count - 1 ];
       repaintRegions [ count - 1 ] = jRectangle;
       count--;
       break iLoop;

      }
    }
  }
}
       return count;
    }
    public Rectangle [ ] getRepaintRegions ( )
    //////////////////////////////////////////////////
    {
      return repaintAll ? ALL_REGIONS : repaintRegions;
    }

If the repaintAll flag is set, the accessor methods of CoalescingRepaint-Collector return the same values that the BooleanRepaintCollector would. If the repaintAll flag is false, the accessor methods return the same values that the SimpleRepaintCollector would, with the exception that repaint regions that overlap are coalesced when the getCount() method is called. Whereas the standard Swing RepaintManager will coalesce all repaint regions on the screen, no matter how far apart they are separated into a single large repaint region, Coalescing-RepaintCollector coalesces only those repaint regions that overlap.

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

Any requests that come in after the repaintAll flag has been set are simply ignored.

public void repaint ( )
/////////////////////////////////////////////////////
{
repaintAll = true;
}
public void reset ( )
///////////////////////////////////////////////////
{
count = 0;
repaintAll = false; }

The repaintAll flag is set the first time a request to repaint the entire component is made during an animation loop iteration and reset at the end of the iteration.

Other Implementations

You should feel free to create your own implementations of interface Repaint-Collector if you feel it would improve animation performance. Another implementation that I have tried, for example, is one that coalesces multiple small repaint requests into a single request after a maximum count is reached. This could be useful when you have a large number of sprites swarming about the entire scene. Since you know the intimate details of your own game, you may be able to come up with a custom implementation of RepaintCollector that is more efficient than general-purpose implementations.

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