Repaint timelines in Trident 1.3

June 6th, 2010

Trident aims to be a general-purpose animation library for Java applications. However, most of the time people talk and refer to animations in the context of pixels on the screen, be it for transitions between different states, rollover effects, smooth scrolling of large content and what not. Trident comes with built-in support for Java based UI toolkits. The three UI specific requirements are addressed by the core Trident library:

  • Automatically respecting the threading rules of the UI toolkits
  • Providing property interpolators for classes that represent graphical objects of the UI toolkits
  • Repainting application windows that have continuous animations

Today i’m going to talk about the last point – repainting application windows. Trident has two special timelines – org.pushingpixels.trident.swing.SwingRepaintTimeline and org.pushingpixels.trident.swt.SWTRepaintTimeline. These are simple utility timelines that can be used to continuously repaint the contents of the specific window / component on every timeline pulse. For example, if you have a continuous emulation of fireworks, you can have “worker” timelines updating the model objects that represent the firework volleys, and one repaint timeline that updates the entire screen based on the current state of all firework volley model objects. This allows you to separate the model updates from the view updates.

However, as Rob Eden pointed out to me this week, these two classes repaint the window / component on every timeline pulse. This can result in unnecessary repaints if the model updates are not done on every timeline pulse as well. In the “snake” example, the model is updated only when the mouse is moving. Once the mouse has stopped moving and all rollover timelines are done, there are no changes to the model, and continuously repainting the screen consumes unnecessary CPU resources.

To address this, both SwingRepaintTimeline and SWTRepaintTimeline now have three new APIs:

  1. setAutoRepaintMode(boolean) – by default the auto repaint mode is true. Application that wishes to control the repaint will call this method with false.
  2. forceRepaintAtNextPulse() – will make the repaint() / redraw() call when the next pulse is fired. This will throw an exception if the timeline is in auto-repaint mode.
  3. setRepaintRectangle(Rectangle) – allows to dynamically change the rectangle to be repainted. Can be used if the bounds of the view that represents the specific model can change dynamically (e.g. when the user resizes the application window).

The snake examples for both Swing and SWT have been updated to show the recommended usage of the first two APIs. Click the button below to run the WebStart version of the Swing demo:

If you’re interested in testing this functionality in your application, take the latest 1.3dev drop (code named Diamond In The Sky) for a spin.