< prev index next >
src/windows/classes/sun/awt/windows/TranslucentWindowPainter.java
Print this page
rev 1556 : 6794764: Translucent windows are completely repainted on every paint event, on Windows
6719382: Printing of AWT components on windows is not working
6726866: Repainting artifacts when resizing or dragging JInternalFrames in non-opaque toplevel
6683775: Painting artifacts is seen when panel is made setOpaque(false) for a translucent window
Reviewed-by: anthony, tdv, alexp
@@ -103,13 +103,14 @@
this.peer = peer;
this.window = (Window)peer.getTarget();
}
/**
- * Creates (if needed), clears and returns the buffer for this painter.
+ * Creates (if needed), clears (if requested) and returns the buffer
+ * for this painter.
*/
- protected abstract Image getBackBuffer();
+ protected abstract Image getBackBuffer(boolean clear);
/**
* Updates the the window associated with this painter with the contents
* of the passed image.
* The image can not be null, and NPE will be thrown if it is.
@@ -121,54 +122,34 @@
* recreated as needed.
*/
public abstract void flush();
/**
- * Updates the window associated with the painter given the passed image.
- * If the passed image is null the painter will use its own buffer for
- * rendering the contents of the window into it and updating the window.
+ * Updates the window associated with the painter.
*
- * If the passed buffer has dimensions different from the window, it is
- * copied into the internal buffer first and the latter is used to update
- * the window.
- *
- * @param bb the image to update the non opaque window with, or null.
- * If not null, the image must be of ARGB_PRE type.
+ * @param repaint indicates if the window should be completely repainted
+ * to the back buffer using {@link java.awt.Window#paintAll} before update.
*/
- public void updateWindow(Image bb) {
+ public void updateWindow(boolean repaint) {
boolean done = false;
- if (bb != null && (window.getWidth() != bb.getWidth(null) ||
- window.getHeight() != bb.getHeight(null)))
- {
- Image ourBB = getBackBuffer();
- Graphics2D g = (Graphics2D)ourBB.getGraphics();
- g.drawImage(bb, 0, 0, null);
- g.dispose();
- bb = ourBB;
- }
- do {
- if (bb == null) {
- bb = getBackBuffer();
+ Image bb = getBackBuffer(repaint);
+ while (!done) {
+ if (repaint) {
Graphics2D g = (Graphics2D)bb.getGraphics();
try {
window.paintAll(g);
} finally {
g.dispose();
}
}
- peer.paintAppletWarning((Graphics2D)bb.getGraphics(),
- bb.getWidth(null), bb.getHeight(null));
-
done = update(bb);
- // in case they passed us a lost VI, next time around we'll use our
- // own bb because we can not validate and restore the contents of
- // their VI
if (!done) {
- bb = null;
+ repaint = true;
+ bb = getBackBuffer(true);
+ }
}
- } while (!done);
}
private static final Image clearImage(Image bb) {
Graphics2D g = (Graphics2D)bb.getGraphics();
int w = bb.getWidth(null);
@@ -188,34 +169,28 @@
*
* This painter handles all types of images passed to its paint(Image)
* method (VI, BI, regular Images).
*/
private static class BIWindowPainter extends TranslucentWindowPainter {
- private WeakReference<BufferedImage> biRef;
+ private BufferedImage backBuffer;
protected BIWindowPainter(WWindowPeer peer) {
super(peer);
}
- private BufferedImage getBIBackBuffer() {
+ @Override
+ protected Image getBackBuffer(boolean clear) {
int w = window.getWidth();
int h = window.getHeight();
- BufferedImage bb = biRef == null ? null : biRef.get();
- if (bb == null || bb.getWidth() != w || bb.getHeight() != h) {
- if (bb != null) {
- bb.flush();
- bb = null;
- }
- bb = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
- biRef = new WeakReference<BufferedImage>(bb);
+ if (backBuffer == null ||
+ backBuffer.getWidth() != w ||
+ backBuffer.getHeight() != h)
+ {
+ flush();
+ backBuffer = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE);
}
- return (BufferedImage)clearImage(bb);
- }
-
- @Override
- protected Image getBackBuffer() {
- return getBIBackBuffer();
+ return clear ? (BufferedImage)clearImage(backBuffer) : backBuffer;
}
@Override
protected boolean update(Image bb) {
VolatileImage viBB = null;
@@ -244,56 +219,49 @@
}
}
}
// copy the passed image into our own buffer, then upload
- BufferedImage bi = getBIBackBuffer();
- Graphics2D g = (Graphics2D)bi.getGraphics();
- g.setComposite(AlphaComposite.Src);
- g.drawImage(bb, 0, 0, null);
+ BufferedImage bi = (BufferedImage)clearImage(backBuffer);
int data[] =
((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
peer.updateWindowImpl(data, bi.getWidth(), bi.getHeight());
return (viBB != null ? !viBB.contentsLost() : true);
}
public void flush() {
- if (biRef != null) {
- biRef.clear();
+ if (backBuffer != null) {
+ backBuffer.flush();
+ backBuffer = null;
}
}
}
/**
* A version of the painter which uses VolatileImage as the internal buffer.
* The window is painted into this VI and then copied into the parent's
* Java heap-based buffer (which is then uploaded to the layered window)
*/
private static class VIWindowPainter extends BIWindowPainter {
- private WeakReference<VolatileImage> viRef;
+ private VolatileImage viBB;
protected VIWindowPainter(WWindowPeer peer) {
super(peer);
}
@Override
- protected Image getBackBuffer() {
+ protected Image getBackBuffer(boolean clear) {
int w = window.getWidth();
int h = window.getHeight();
GraphicsConfiguration gc = peer.getGraphicsConfiguration();
- VolatileImage viBB = viRef == null ? null : viRef.get();
-
if (viBB == null || viBB.getWidth() != w || viBB.getHeight() != h ||
viBB.validate(gc) == IMAGE_INCOMPATIBLE)
{
- if (viBB != null) {
- viBB.flush();
- viBB = null;
- }
+ flush();
if (gc instanceof AccelGraphicsConfig) {
AccelGraphicsConfig agc = ((AccelGraphicsConfig)gc);
viBB = agc.createCompatibleVolatileImage(w, h,
TRANSLUCENT,
@@ -301,26 +269,21 @@
}
if (viBB == null) {
viBB = gc.createCompatibleVolatileImage(w, h, TRANSLUCENT);
}
viBB.validate(gc);
- viRef = new WeakReference<VolatileImage>(viBB);
}
- return clearImage(viBB);
+ return clear ? clearImage(viBB) : viBB;
}
@Override
public void flush() {
- if (viRef != null) {
- VolatileImage viBB = viRef.get();
if (viBB != null) {
viBB.flush();
viBB = null;
}
- viRef.clear();
- }
}
}
/**
* Optimized version of hw painter. Uses VolatileImages for the
< prev index next >