Methods Summary |
---|
private java.awt.Image | _getOffscreenBuffer(java.awt.Component c, int proposedWidth, int proposedHeight)
Dimension maxSize = getDoubleBufferMaximumSize();
DoubleBufferInfo doubleBuffer = null;
int width, height;
if (standardDoubleBuffer == null) {
standardDoubleBuffer = new DoubleBufferInfo();
}
doubleBuffer = standardDoubleBuffer;
width = proposedWidth < 1? 1 :
(proposedWidth > maxSize.width? maxSize.width : proposedWidth);
height = proposedHeight < 1? 1 :
(proposedHeight > maxSize.height? maxSize.height : proposedHeight);
if (doubleBuffer.needsReset || (doubleBuffer.image != null &&
(doubleBuffer.size.width < width ||
doubleBuffer.size.height < height))) {
doubleBuffer.needsReset = false;
if (doubleBuffer.image != null) {
doubleBuffer.image.flush();
doubleBuffer.image = null;
}
width = Math.max(doubleBuffer.size.width, width);
height = Math.max(doubleBuffer.size.height, height);
}
Image result = doubleBuffer.image;
if (doubleBuffer.image == null) {
result = c.createImage(width , height);
doubleBuffer.size = new Dimension(width, height);
if (c instanceof JComponent) {
((JComponent)c).setCreatedDoubleBuffer(true);
doubleBuffer.image = result;
}
// JComponent will inform us when it is no longer valid
// (via removeNotify) we have no such hook to other components,
// therefore we don't keep a ref to the Component
// (indirectly through the Image) by stashing the image.
}
return result;
|
public void | addDirtyRegion(javax.swing.JComponent c, int x, int y, int w, int h)Add a component in the list of components that should be refreshed.
If c already has a dirty region, the rectangle (x,y,w,h)
will be unioned with the region that should be redrawn.
/* Special cases we don't have to bother with.
*/
if ((w <= 0) || (h <= 0) || (c == null)) {
return;
}
if ((c.getWidth() <= 0) || (c.getHeight() <= 0)) {
return;
}
if (extendDirtyRegion(c, x, y, w, h)) {
// Component was already marked as dirty, region has been
// extended, no need to continue.
return;
}
/* Make sure that c and all it ancestors (up to an Applet or
* Window) are visible. This loop has the same effect as
* checking c.isShowing() (and note that it's still possible
* that c is completely obscured by an opaque ancestor in
* the specified rectangle).
*/
Component root = null;
// Note: We can't synchronize around this, Frame.getExtendedState
// is synchronized so that if we were to synchronize around this
// it could lead to the possibility of getting locks out
// of order and deadlocking.
for (Container p = c; p != null; p = p.getParent()) {
if (!p.isVisible() || (p.getPeer() == null)) {
return;
}
if ((p instanceof Window) || (p instanceof Applet)) {
// Iconified frames are still visible!
if (p instanceof Frame &&
(((Frame)p).getExtendedState() & Frame.ICONIFIED) ==
Frame.ICONIFIED) {
return;
}
root = p;
break;
}
}
if (root == null) return;
synchronized(this) {
if (extendDirtyRegion(c, x, y, w, h)) {
// In between last check and this check another thread
// queued up runnable, can bail here.
return;
}
dirtyComponents.put(c, new Rectangle(x, y, w, h));
}
/* Queues a Runnable that calls validateInvalidComponents() and
* rm.paintDirtyRegions() with SwingUtilities.invokeLater().
*/
SystemEventQueueUtilities.queueComponentWorkRequest(root);
|
public synchronized void | addInvalidComponent(javax.swing.JComponent invalidComponent)Mark the component as in need of layout and queue a runnable
for the event dispatching thread that will validate the components
first isValidateRoot() ancestor.
Component validateRoot = null;
/* Find the first JComponent ancestor of this component whose
* isValidateRoot() method returns true.
*/
for(Component c = invalidComponent; c != null; c = c.getParent()) {
if ((c instanceof CellRendererPane) || (c.getPeer() == null)) {
return;
}
if ((c instanceof JComponent) && (((JComponent)c).isValidateRoot())) {
validateRoot = c;
break;
}
}
/* There's no validateRoot to apply validate to, so we're done.
*/
if (validateRoot == null) {
return;
}
/* If the validateRoot and all of its ancestors aren't visible
* then we don't do anything. While we're walking up the tree
* we find the root Window or Applet.
*/
Component root = null;
for(Component c = validateRoot; c != null; c = c.getParent()) {
if (!c.isVisible() || (c.getPeer() == null)) {
return;
}
if ((c instanceof Window) || (c instanceof Applet)) {
root = c;
break;
}
}
if (root == null) {
return;
}
/* Lazily create the invalidateComponents vector and add the
* validateRoot if it's not there already. If this validateRoot
* is already in the vector, we're done.
*/
if (invalidComponents == null) {
invalidComponents = new Vector();
}
else {
int n = invalidComponents.size();
for(int i = 0; i < n; i++) {
if(validateRoot == (Component)(invalidComponents.elementAt(i))) {
return;
}
}
}
invalidComponents.addElement(validateRoot);
/* Queues a Runnable that calls RepaintManager.validateInvalidComponents()
* and RepaintManager.paintDirtyRegions() with SwingUtilities.invokeLater().
*/
SystemEventQueueUtilities.queueComponentWorkRequest(root);
|
void | collectDirtyComponents(java.util.Hashtable dirtyComponents, javax.swing.JComponent dirtyComponent, java.util.Vector roots)
int dx, dy, rootDx, rootDy;
Component component, rootDirtyComponent,parent;
//Rectangle tmp;
Rectangle cBounds;
// Find the highest parent which is dirty. When we get out of this
// rootDx and rootDy will contain the translation from the
// rootDirtyComponent's coordinate system to the coordinates of the
// original dirty component. The tmp Rect is also used to compute the
// visible portion of the dirtyRect.
component = rootDirtyComponent = dirtyComponent;
int x = dirtyComponent.getX();
int y = dirtyComponent.getY();
int w = dirtyComponent.getWidth();
int h = dirtyComponent.getHeight();
dx = rootDx = 0;
dy = rootDy = 0;
tmp.setBounds((Rectangle) dirtyComponents.get(dirtyComponent));
// System.out.println("Collect dirty component for bound " + tmp +
// "component bounds is " + cBounds);;
SwingUtilities.computeIntersection(0,0,w,h,tmp);
if (tmp.isEmpty()) {
// System.out.println("Empty 1");
return;
}
for(;;) {
parent = component.getParent();
if(parent == null)
break;
if(!(parent instanceof JComponent))
break;
component = parent;
dx += x;
dy += y;
tmp.setLocation(tmp.x + x, tmp.y + y);
x = component.getX();
y = component.getY();
w = component.getWidth();
h = component.getHeight();
tmp = SwingUtilities.computeIntersection(0,0,w,h,tmp);
if (tmp.isEmpty()) {
// System.out.println("Empty 2");
return;
}
if (dirtyComponents.get(component) != null) {
rootDirtyComponent = component;
rootDx = dx;
rootDy = dy;
}
}
if (dirtyComponent != rootDirtyComponent) {
Rectangle r;
tmp.setLocation(tmp.x + rootDx - dx,
tmp.y + rootDy - dy);
r = (Rectangle)dirtyComponents.get(rootDirtyComponent);
SwingUtilities.computeUnion(tmp.x,tmp.y,tmp.width,tmp.height,r);
}
// If we haven't seen this root before, then we need to add it to the
// list of root dirty Views.
if (!roots.contains(rootDirtyComponent))
roots.addElement(rootDirtyComponent);
|
public static javax.swing.RepaintManager | currentManager(java.awt.Component c)Return the RepaintManager for the calling thread given a Component.
String vib = (String) java.security.AccessController.doPrivileged(
new GetPropertyAction("swing.volatileImageBufferEnabled"));
volatileImageBufferEnabled = (vib == null || vib.equals("true"));
// Note: SystemEventQueueUtilities.ComponentWorkRequest passes
// in null as the component, so if component is ever used to
// determine the current RepaintManager, SystemEventQueueUtilities
// will need to be modified accordingly.
RepaintManager result = (RepaintManager) SwingUtilities.appContextGet(repaintManagerKey);
if(result == null) {
result = new RepaintManager();
SwingUtilities.appContextPut(repaintManagerKey, result);
}
return result;
|
public static javax.swing.RepaintManager | currentManager(javax.swing.JComponent c)Return the RepaintManager for the calling thread given a JComponent.
Note: This method exists for backward binary compatibility with earlier
versions of the Swing library. It simply returns the result returned by
{@link #currentManager(Component)}.
return currentManager((Component)c);
|
private synchronized boolean | extendDirtyRegion(java.awt.Component c, int x, int y, int w, int h)Extends the dirty region for the specified component to include
the new region.
Rectangle r = (Rectangle)dirtyComponents.get(c);
if (r != null) {
// A non-null r implies c is already marked as dirty,
// and that the parent is valid. Therefore we can
// just union the rect and bail.
SwingUtilities.computeUnion(x, y, w, h, r);
return true;
}
return false;
|
public java.awt.Rectangle | getDirtyRegion(javax.swing.JComponent aComponent)Return the current dirty region for a component.
Return an empty rectangle if the component is not
dirty.
Rectangle r = null;
synchronized(this) {
r = (Rectangle)dirtyComponents.get(aComponent);
}
if(r == null)
return new Rectangle(0,0,0,0);
else
return new Rectangle(r);
|
public java.awt.Dimension | getDoubleBufferMaximumSize()Returns the maximum double buffer size.
if (doubleBufferMaxSize == null) {
try {
doubleBufferMaxSize = Toolkit.getDefaultToolkit().getScreenSize();
} catch (HeadlessException e) {
doubleBufferMaxSize = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
}
return doubleBufferMaxSize;
|
public java.awt.Image | getOffscreenBuffer(java.awt.Component c, int proposedWidth, int proposedHeight)Return the offscreen buffer that should be used as a double buffer with
the component c .
By default there is a double buffer per RepaintManager.
The buffer might be smaller than (proposedWidth,proposedHeight)
This happens when the maximum double buffer size as been set for the receiving
repaint manager.
return _getOffscreenBuffer(c, proposedWidth, proposedHeight);
|
public java.awt.Image | getVolatileOffscreenBuffer(java.awt.Component c, int proposedWidth, int proposedHeight)Return a volatile offscreen buffer that should be used as a
double buffer with the specified component c .
The image returned will be an instance of VolatileImage, or null
if a VolatileImage object could not be instantiated.
This buffer might be smaller than (proposedWidth,proposedHeight) .
This happens when the maximum double buffer size has been set for this
repaint manager.
GraphicsConfiguration config = c.getGraphicsConfiguration();
if (config == null) {
config = GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
}
Dimension maxSize = getDoubleBufferMaximumSize();
int width = proposedWidth < 1 ? 1 :
(proposedWidth > maxSize.width? maxSize.width : proposedWidth);
int height = proposedHeight < 1 ? 1 :
(proposedHeight > maxSize.height? maxSize.height : proposedHeight);
VolatileImage image = (VolatileImage)volatileMap.get(config);
if (image == null || image.getWidth() < width ||
image.getHeight() < height) {
if (image != null) {
image.flush();
}
image = config.createCompatibleVolatileImage(width, height);
volatileMap.put(config, image);
}
return image;
|
public boolean | isCompletelyDirty(javax.swing.JComponent aComponent)Convenience method that returns true if aComponent will be completely
painted during the next paintDirtyRegions(). If computing dirty regions is
expensive for your component, use this method and avoid computing dirty region
if it return true.
Rectangle r;
r = getDirtyRegion(aComponent);
if(r.width == Integer.MAX_VALUE &&
r.height == Integer.MAX_VALUE)
return true;
else
return false;
|
public boolean | isDoubleBufferingEnabled()Returns true if this RepaintManager is double buffered.
The default value for this property may vary from platform
to platform. On platforms where native double buffering
is supported in the AWT, the default value will be false
to avoid unnecessary buffering in Swing.
On platforms where native double buffering is not supported,
the default value will be true .
return doubleBufferingEnabled;
|
public void | markCompletelyClean(javax.swing.JComponent aComponent)Mark a component completely clean. aComponent will not
get painted during the next paintDirtyRegions() call.
synchronized(this) {
dirtyComponents.remove(aComponent);
}
|
public void | markCompletelyDirty(javax.swing.JComponent aComponent)Mark a component completely dirty. aComponent will be
completely painted during the next paintDirtyRegions() call.
addDirtyRegion(aComponent,0,0,Integer.MAX_VALUE,Integer.MAX_VALUE);
|
public void | paintDirtyRegions()Paint all of the components that have been marked dirty.
int i, count;
Vector roots;
JComponent dirtyComponent;
synchronized(this) { // swap for thread safety
Hashtable tmp = tmpDirtyComponents;
tmpDirtyComponents = dirtyComponents;
dirtyComponents = tmp;
dirtyComponents.clear();
}
count = tmpDirtyComponents.size();
if (count == 0) {
return;
}
Rectangle rect;
int localBoundsX = 0;
int localBoundsY = 0;
int localBoundsH = 0;
int localBoundsW = 0;
Enumeration keys;
roots = new Vector(count);
keys = tmpDirtyComponents.keys();
while(keys.hasMoreElements()) {
dirtyComponent = (JComponent) keys.nextElement();
collectDirtyComponents(tmpDirtyComponents, dirtyComponent, roots);
}
count = roots.size();
// System.out.println("roots size is " + count);
for(i=0 ; i < count ; i++) {
dirtyComponent = (JComponent) roots.elementAt(i);
rect = (Rectangle) tmpDirtyComponents.get(dirtyComponent);
// System.out.println("Should refresh :" + rect);
localBoundsH = dirtyComponent.getHeight();
localBoundsW = dirtyComponent.getWidth();
SwingUtilities.computeIntersection(localBoundsX,
localBoundsY,
localBoundsW,
localBoundsH,
rect);
// System.out.println("** paint of " + dirtyComponent + rect);
if (rect.x == 0 && rect.y == 0 &&
rect.width == dirtyComponent.getWidth() &&
rect.height == dirtyComponent.getHeight()) {
Container parent = dirtyComponent.getParent();
ComponentPeer parentPeer;
if (parent != null && !parent.isLightweight() &&
(parentPeer = parent.getPeer()) != null) {
// Cancel any pending paints on the heavy weight peer.
// This avoid duplicate painting.
((ContainerPeer)parentPeer).cancelPendingPaint(
dirtyComponent.getX(),
dirtyComponent.getY(),
rect.width, rect.height);
}
}
dirtyComponent.paintImmediately(rect.x,rect.y,rect.width,rect.height);
}
tmpDirtyComponents.clear();
|
public synchronized void | removeInvalidComponent(javax.swing.JComponent component)Remove a component from the list of invalid components.
if(invalidComponents != null) {
int index = invalidComponents.indexOf(component);
if(index != -1) {
invalidComponents.removeElementAt(index);
}
}
|
void | resetDoubleBuffer()This resets the double buffer. Actually, it marks the double buffer
as invalid, the double buffer will then be recreated on the next
invocation of getOffscreenBuffer.
if (standardDoubleBuffer != null) {
standardDoubleBuffer.needsReset = true;
}
|
void | resetVolatileDoubleBuffer(java.awt.GraphicsConfiguration gc)This resets the volatile double buffer.
Image image = (Image)volatileMap.remove(gc);
if (image != null) {
image.flush();
}
|
public static void | setCurrentManager(javax.swing.RepaintManager aRepaintManager)Set the RepaintManager that should be used for the calling
thread. aRepaintManager will become the current RepaintManager
for the calling thread's thread group.
if (aRepaintManager != null) {
SwingUtilities.appContextPut(repaintManagerKey, aRepaintManager);
} else {
SwingUtilities.appContextRemove(repaintManagerKey);
}
|
public void | setDoubleBufferMaximumSize(java.awt.Dimension d)Set the maximum double buffer size.
doubleBufferMaxSize = d;
if (standardDoubleBuffer != null && standardDoubleBuffer.image != null) {
if (standardDoubleBuffer.image.getWidth(null) > d.width ||
standardDoubleBuffer.image.getHeight(null) > d.height) {
standardDoubleBuffer.image = null;
}
}
// Clear out the VolatileImages
Iterator gcs = volatileMap.keySet().iterator();
while (gcs.hasNext()) {
GraphicsConfiguration gc = (GraphicsConfiguration)gcs.next();
VolatileImage image = (VolatileImage)volatileMap.get(gc);
if (image.getWidth() > d.width || image.getHeight() > d.height) {
image.flush();
gcs.remove();
}
}
|
public void | setDoubleBufferingEnabled(boolean aFlag)Enables or disables double buffering in this RepaintManager.
CAUTION: The default value for this property is set for optimal
paint performance on the given platform and it is not recommended
that programs modify this property directly.
doubleBufferingEnabled = aFlag;
|
public synchronized java.lang.String | toString()Returns a string that displays and identifies this
object's properties.
StringBuffer sb = new StringBuffer();
if(dirtyComponents != null)
sb.append("" + dirtyComponents);
return sb.toString();
|
boolean | useVolatileDoubleBuffer()Returns true if we should use the Image returned
from getVolatileOffscreenBuffer to do double buffering.
return volatileImageBufferEnabled;
|
public void | validateInvalidComponents()Validate all of the components that have been marked invalid.
Vector ic;
synchronized(this) {
if(invalidComponents == null) {
return;
}
ic = invalidComponents;
invalidComponents = null;
}
int n = ic.size();
for(int i = 0; i < n; i++) {
((Component)ic.elementAt(i)).validate();
}
|