jCpSim logo
Java CardioPulmonary SIMulations
- Version 0.2.02 (2007-05-26) -

DxRepaintManager

Unites and repaints dirty regions according to the distance in between them.

Or: how to repaint only those areas that have changed.

This text and the presented source code refers to Java build 1.6.0-b105.

Tested with Java 1.6 on Linux and Java 1.5 on MS Windows.

The problem

The current javax.swing.RepaintManager repaints the whole bounding rectangle of all dirty regions of a Component. This causes a repaint of the whole area of the component even if only some small updates occur on opposing corners of that component.

The solution

  • javax.swing.DxRepaintManager can collect more than one bounding rectangle.
  • If a new dirty region is added and the distance (Dx) from that region to some bounding rectangle is less or equal than a given maxDistance the dirty region is added to that rectangle.
  • If the dirty region could not be added to some bounding rectangle (because it was too far away) a new bounding rectangle is created which contains the dirty region.

A Java Web Start example

  • Run jCpSim.
  • Display dirty regions (Menu: Settings - Debug - show region management).
  • Select distance (Menu: Settings - Debug - unite dirty regions).

The software

You need all the files in the javax.swing.* package of jCpSim:

Then you have to put the following lines in your code:

import javax.swing.RepaintManager;
import javax.swing.DxRepaintManager;

...
RepaintManager.setCurrentManager(new DxRepaintManager());
DxRepaintManager.currentManager(null).setMaxDistance(20);

Here is an example: TestRegionManagement.java

What about Piccolo?

DxRepaintManager was written to speed up graphics in Piccolo PComponents (see example above).

It might be usable for ordinary Swing programs as well (not tested).

It seems to run with PSwing. But edu.umd.cs.piccolox.pswing.PSwingRepaintManager has to be modified: it should extend DxRepaintManager instead of RepaintManager. No other changes to the Piccolo sources are needed.

PSwingCanvas then sets DxRepaintManager as the current manager. You may change the behaviour of DxRepaintManager with:

import javax.swing.DxRepaintManager;

...
DxRepaintManager.currentManager(null).setMaxDistance(20);

The files

DxRepaintManager.java

this

private Map<Component,Rectangle>    dirtyComponents;
private Map<Component,Rectangle> tmpDirtyComponents;

was replaced by

private DirtyComponents    dirtyComponents;
private DirtyComponents tmpDirtyComponents;

static  int                          maxDistance;
public  void setMaxDistance(int d) { maxDistance = d; }
public  int  getMaxDistance()      { return maxDistance; }

The most relevant methods that were modified were

private void addDirtyRegion0(Container c, int x, int y, int w, int h)

and

private void paintDirtyRegions(DirtyComponents tmpDirtyComponents)

DirtyComponents.java

Manages a map of all dirty regions of each component:

public  Map<Component,DirtyRegions> components;

A lot of code was moved from RepaintManager to this class.

DirtyRegions.java

Manages the bounding rectangles of all dirty regions of a JComponent.

DxBufferStrategyPaintManager.java and DxSystemEventQueueUtilities.java

Are the same as BufferStrategyPaintManager and SystemEventQueueUtilities - only that all references to RepaintManager have been changed to DxRepaintManager. Methods in both classes are called by (Dx)RepaintManager

Related work

A similar algorithm (without source code) is described in
Weaver CE, Livny M: Improving Visualization Interactivity in Java
(Section 4.3: 'Multi-Rectangle Invalidation').