6884960: java/awt/Window/TranslucentJAppletTest/TranslucentJAppletTest.java fails
Summary: Support painting heavyweight components in transparent windows.
Reviewed-by: art, alexp
--- a/jdk/src/share/classes/javax/swing/JComponent.java Wed Oct 14 16:32:38 2009 +0400
+++ b/jdk/src/share/classes/javax/swing/JComponent.java Wed Oct 14 19:23:15 2009 +0400
@@ -795,7 +795,6 @@
* @see java.awt.Container#paint
*/
protected void paintChildren(Graphics g) {
- boolean isJComponent;
Graphics sg = g;
synchronized(getTreeLock()) {
@@ -826,12 +825,21 @@
}
}
boolean printing = getFlag(IS_PRINTING);
+ final Window window = SwingUtilities.getWindowAncestor(this);
+ final boolean isWindowOpaque = window == null || window.isOpaque();
for (; i >= 0 ; i--) {
Component comp = getComponent(i);
- isJComponent = (comp instanceof JComponent);
- if (comp != null &&
- (isJComponent || isLightweightComponent(comp)) &&
- (comp.isVisible() == true)) {
+ if (comp == null) {
+ continue;
+ }
+
+ final boolean isJComponent = comp instanceof JComponent;
+
+ // Enable painting of heavyweights in non-opaque windows.
+ // See 6884960
+ if ((!isWindowOpaque || isJComponent ||
+ isLightweightComponent(comp)) && comp.isVisible())
+ {
Rectangle cr;
cr = comp.getBounds(tmpRect);
@@ -887,6 +895,8 @@
}
}
} else {
+ // The component is either lightweight, or
+ // heavyweight in a non-opaque window
if (!printing) {
comp.paint(cg);
}
--- a/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Wed Oct 14 16:32:38 2009 +0400
+++ b/jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java Wed Oct 14 19:23:15 2009 +0400
@@ -551,8 +551,34 @@
final static Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
public Graphics getGraphics() {
+ if (isDisposed()) {
+ return null;
+ }
+
+ Component target = (Component)getTarget();
+ Window window = SunToolkit.getContainingWindow(target);
+ if (window != null && !window.isOpaque()) {
+ // Non-opaque windows do not support heavyweight children.
+ // Redirect all painting to the Window's Graphics instead.
+ // The caller is responsible for calling the
+ // WindowPeer.updateWindow() after painting has finished.
+ int x = 0, y = 0;
+ for (Component c = target; c != window; c = c.getParent()) {
+ x += c.getX();
+ y += c.getY();
+ }
+
+ Graphics g =
+ ((WWindowPeer)window.getPeer()).getTranslucentGraphics();
+
+ g.translate(x, y);
+ g.clipRect(0, 0, target.getWidth(), target.getHeight());
+
+ return g;
+ }
+
SurfaceData surfaceData = this.surfaceData;
- if (!isDisposed() && surfaceData != null) {
+ if (surfaceData != null) {
/* Fix for bug 4746122. Color and Font shouldn't be null */
Color bgColor = background;
if (bgColor == null) {
--- a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Wed Oct 14 16:32:38 2009 +0400
+++ b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Wed Oct 14 19:23:15 2009 +0400
@@ -578,11 +578,17 @@
}
}
+ public final Graphics getTranslucentGraphics() {
+ synchronized (getStateLock()) {
+ return isOpaque ? null : painter.getBackBuffer(false).getGraphics();
+ }
+ }
+
@Override
public Graphics getGraphics() {
synchronized (getStateLock()) {
if (!isOpaque) {
- return painter.getBackBuffer(false).getGraphics();
+ return getTranslucentGraphics();
}
}
return super.getGraphics();