United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6725365 Per-pixel transparency must only be available for undecorated frames/windows
JDK-6725365 : Per-pixel transparency must only be available for undecorated frames/windows

Details
Type:
Bug
Submit Date:
2008-07-14
Status:
Resolved
Updated Date:
2011-03-15
Project Name:
JDK
Resolved Date:
2008-09-02
Component:
client-libs
OS:
windows_vista,generic
Sub-Component:
java.awt
CPU:
generic
Priority:
P2
Resolution:
Fixed
Affected Versions:
6u10
Fixed Versions:
6u10 (b31)

Related Reports
Backport:
Duplicate:
Relates:
Relates:
Relates:

Sub Tasks

Description
It was initially considered to allow using the per-pixel transparency mode for undecorated windows only, because it was unclear what to do with the natively-drawn window decorations. Especially on MS Windows platform where the decorations stop reacting on mouse clicks but still are drawn in some cases once the window enters the non-opaque mode.

For some reason the code checking for this got lost, and curretnly the com.sun.awt.AWTUtilities.setWindowOpaque() method does not throw an exception in case the windod is decorated, but it should do so.

If the user simply forgets to call the setUndecorated(true) method, he easily gets non-functional decorations on MS Windows Vista. The visual artifact is considered quite severe.

The bug is reported here: http://forums.java.net/jive/thread.jspa?threadID=43881&tstart=0

                                    

Comments
EVALUATION

The code checking for isDecorated() got lost.
                                     
2008-07-14
SUGGESTED FIX

--- old/src/share/classes/com/sun/awt/AWTUtilities.java	2008-07-25 14:17:12.000000000 +0400
+++ new/src/share/classes/com/sun/awt/AWTUtilities.java	2008-07-25 14:17:12.000000000 +0400
@@ -340,6 +340,13 @@
      * <p>Also note that the window must not be in the full-screen mode
      * when making it non-opaque. Otherwise the IllegalArgumentException
      * is thrown.
+     * <p>If the window is a {@code Frame} or a {@code Dialog}, the window must
+     * be undecorated prior to enabling the per-pixel translucency effect (see
+     * {@link Frame#setUndecorated()} and/or {@link Dialog#setUndecorated()}).
+     * If the window becomes decorated through a subsequent call to the
+     * corresponding {@code setUndecorated()} method, the per-pixel
+     * translucency effect will be disabled and the opaque property reset to
+     * {@code true}.
      * <p>Depending on the platform, the method may return without
      * effecting the opaque property of the window if the window has a non-null
      * warning string ({@link Window#getWarningString()}). In this case 
@@ -355,6 +362,7 @@
      *                                  method returns false
      * @throws IllegalArgumentException if the window is in full screen mode, 
      *                                  and the isOpaque is false
+     * @throws IllegalArgumentException if the window is decorated.
      * @throws UnsupportedOperationException if the PERPIXEL_TRANSLUCENT 
      *                                       translucency kind is not supported
      */
@@ -363,17 +371,24 @@
             throw new NullPointerException(
                     "The window argument should not be null.");
         }
-        if (!isTranslucencyCapable(
+        if (!isOpaque && !isTranslucencyCapable(
                     window.getGraphicsConfiguration())) {
             throw new IllegalArgumentException(
                     "The window must use a translucency-compatible graphics configuration");
         }
-        if (window.getGraphicsConfiguration().getDevice().getFullScreenWindow()
-                == window && !isOpaque) {
+        if (!isOpaque && window.getGraphicsConfiguration().getDevice().getFullScreenWindow()
+                == window) {
             throw new IllegalArgumentException(
                     "The effects for full-screen windows are not supported.");
         }
-        if (!isTranslucencySupported(Translucency.PERPIXEL_TRANSLUCENT)) {
+        if (!isOpaque && 
+                ((window instanceof Frame && !((Frame)window).isUndecorated()) ||
+                 (window instanceof Dialog && !((Dialog)window).isUndecorated())))
+        {
+            throw new IllegalArgumentException(
+                    "The effects for decorated windows are not supported.");
+        }
+        if (!isOpaque && !isTranslucencySupported(Translucency.PERPIXEL_TRANSLUCENT)) {
             throw new UnsupportedOperationException(
                     "The PERPIXEL_TRANSLUCENT translucency kind is not supported");
         }
--- old/src/share/classes/java/awt/Dialog.java	2008-07-25 14:17:12.000000000 +0400
+++ new/src/share/classes/java/awt/Dialog.java	2008-07-25 14:17:12.000000000 +0400
@@ -15,6 +15,7 @@
 import java.util.Vector;
 import java.util.Iterator;
 import sun.awt.AppContext;
+import sun.awt.AWTAccessor;
 import sun.awt.SunToolkit;
 import sun.awt.PeerEvent;
 import java.lang.ref.WeakReference;
@@ -1321,6 +1322,16 @@
             if (isDisplayable()) {
                 throw new IllegalComponentStateException("The dialog is displayable.");
             }
+            if (!undecorated) {
+                //XXX: this needs to be documented in a further release,
+                //or better: we may throw an exception here.
+                if (!AWTAccessor.getWindowAccessor().isOpaque(this)) {
+                    AWTAccessor.getWindowAccessor().setOpaque(this, true);
+                }
+                if (AWTAccessor.getWindowAccessor().getShape(this) != null) {
+                    AWTAccessor.getWindowAccessor().setShape(this, null);
+                }
+            }
             this.undecorated = undecorated;
         }
     }
--- old/src/share/classes/java/awt/Frame.java	2008-07-25 14:17:13.000000000 +0400
+++ new/src/share/classes/java/awt/Frame.java	2008-07-25 14:17:13.000000000 +0400
@@ -18,6 +18,7 @@
 import java.io.IOException;
 import sun.awt.AppContext;
 import sun.awt.SunToolkit;
+import sun.awt.AWTAccessor;
 import java.lang.ref.WeakReference;
 import javax.accessibility.*;
 
@@ -809,6 +810,16 @@
             if (isDisplayable()) {
                 throw new IllegalComponentStateException("The frame is displayable.");
             }
+            if (!undecorated) {
+                //XXX: this needs to be documented in a further release,
+                //or better: we may throw an exception here.
+                if (!AWTAccessor.getWindowAccessor().isOpaque(this)) {
+                    AWTAccessor.getWindowAccessor().setOpaque(this, true);
+                }
+                if (AWTAccessor.getWindowAccessor().getShape(this) != null) {
+                    AWTAccessor.getWindowAccessor().setShape(this, null);
+                }
+            }
             this.undecorated = undecorated;
         }
     }
                                     
2008-07-14



Hardware and Software, Engineered to Work Together