United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6648996 Frame.printAll() invoked on a non-opaque window prints black background
JDK-6648996 : Frame.printAll() invoked on a non-opaque window prints black background

Details
Type:
Bug
Submit Date:
2008-01-10
Status:
Resolved
Updated Date:
2011-01-19
Project Name:
JDK
Resolved Date:
2008-02-14
Component:
client-libs
OS:
generic
Sub-Component:
java.awt
CPU:
generic
Priority:
P2
Resolution:
Fixed
Affected Versions:
6u10
Fixed Versions:
6u10 (b12)

Related Reports
Relates:
Relates:

Sub Tasks

Description
When using the API introduced with the feature described at the CR 6633275, and making a frame non-opaque (AWTUtilities.setWindowOpaque(frame, false)), the frame is displayed as a translucent top-level window on the screen. The background of the frame becomes invisible, and only the explitcitly painted pixels are visibles (like those belonging to the Swing components put onto the frame).

However, when the Frame.printAll() method is used to print the frame contents on the paper, the area occupied by the invisible background gets printed with black color on the paper which is not correct. 

Expected behavior: nothing should be printed at the areas occupied by the background of the frame if these areas are invisible on the screen because the frame is non-opaque.

                                    

Comments
WORK AROUND

While printing one may temporary make the frame being opaque.
                                     
2008-01-10
EVALUATION

Actually the code for the translucency/shapes feature (6633275) has broken the system dialogs under MS Windows (FileDialog and PrintDialog). Using these dilogs causes throwing the NullPointerException("pData is null"). This happens because the implementation of the mentioned dialogs doesn't use native objects to represent the system dislogs: only the java-sized peers exist. While initializing a window (be it a regular java window, or a system dialog which is a window as well from the point of view of Java), the applyShape() method gets invoked (see java.awt.Window.addNotify()) to initialize any set shape for this window. The method at the end of the call-chain executes a static function at the native code (say, AwtComponent::SetRectangularShape()), which in turn tries to retrive the pointer to the native object (an instance of the AwtComponent class) which is the native part of the peer. As this native part doesn't exist for system dialogs, the exception gets generated.

The fix for this CR fixes a couple of printing issue, and it's supposed to be integrated into the 6u10 asap as this is a bug in the newly introduced feature. So is the Print/FileDialog fix, and therefore it is reasonable to combine these fixes.

Concerning the actual printing issue. The cause of the problem is the WComponentPeer.print() method which uses BufferedImage.TYPE_INT_RGB buffered images instead of the BufferedImage.TYPE_INT_ARGB. The first kind of images doesn't support the translucency, and so such images interpret the color value of zero (32 bits) as a black color, not taking into account the alpha component (the 4th byte) which is also null, and therefore represents a transparent color. Using an ARGB image fixes the problem.
                                     
2008-01-18
SUGGESTED FIX

--- old/src/windows/classes/sun/awt/windows/WCanvasPeer.java	2008-01-18 15:21:05.000000000 +0300
+++ new/src/windows/classes/sun/awt/windows/WCanvasPeer.java	2008-01-18 15:21:05.000000000 +0300
@@ -10,6 +10,7 @@
 import java.awt.peer.*;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Method;
+import sun.awt.AWTAccessor;
 import sun.awt.SunToolkit;
 import sun.awt.Win32GraphicsDevice;
 import sun.awt.PaintEventDispatcher;
@@ -100,18 +101,22 @@
     }
 
     public void print(Graphics g) {
-	Dimension d = ((Component)target).getSize();
-        if (g instanceof Graphics2D ||
-	    g instanceof sun.awt.Graphics2Delegate) {
-	    // background color is setup correctly, so just use clearRect
-	    g.clearRect(0, 0, d.width, d.height);
-	} else {
-	    // emulate clearRect
-	    g.setColor(((Component)target).getBackground());
-	    g.fillRect(0, 0, d.width, d.height);
-	    g.setColor(((Component)target).getForeground());
-	}
-	super.print(g);
+        if (!(target instanceof Window) || 
+                AWTAccessor.getWindowAccessor().isOpaque((Window)target)) 
+        {
+            Dimension d = ((Component)target).getSize();
+            if (g instanceof Graphics2D ||
+                    g instanceof sun.awt.Graphics2Delegate) {
+                // background color is setup correctly, so just use clearRect
+                g.clearRect(0, 0, d.width, d.height);
+            } else {
+                // emulate clearRect
+                g.setColor(((Component)target).getBackground());
+                g.fillRect(0, 0, d.width, d.height);
+                g.setColor(((Component)target).getForeground());
+            }
+        }
+        super.print(g);
     }
     
     public boolean shouldClearRectBeforePaint() {
--- old/src/windows/classes/sun/awt/windows/WComponentPeer.java	2008-01-18 15:21:05.000000000 +0300
+++ new/src/windows/classes/sun/awt/windows/WComponentPeer.java	2008-01-18 15:21:05.000000000 +0300
@@ -253,7 +253,7 @@
             int[] pix = createPrintedPixels(0, startY, totalW, h);
             if (pix != null) {
                 BufferedImage bim = new BufferedImage(totalW, h,
-                                              BufferedImage.TYPE_INT_RGB);
+                                              BufferedImage.TYPE_INT_ARGB);
                 bim.setRGB(0, 0, totalW, h, pix, 0, totalW);
                 g.drawImage(bim, 0, startY, null);
                 bim.flush();
--- old/src/windows/classes/sun/awt/windows/WFileDialogPeer.java	2008-01-18 15:21:05.000000000 +0300
+++ new/src/windows/classes/sun/awt/windows/WFileDialogPeer.java	2008-01-18 15:21:05.000000000 +0300
@@ -207,4 +207,10 @@
     public boolean isRestackSupported() {
         return false;
     }
+
+    // The effects are not supported for system dialogs.
+    public void applyShape(sun.java2d.pipe.Region shape) {}
+    public void setOpacity(float opacity) {}
+    public void setOpaque(boolean isOpaque) {}
+    public void updateWindow(java.awt.image.BufferedImage backBuffer) {}
 }
--- old/src/windows/classes/sun/awt/windows/WPrintDialogPeer.java	2008-01-18 15:21:05.000000000 +0300
+++ new/src/windows/classes/sun/awt/windows/WPrintDialogPeer.java	2008-01-18 15:21:05.000000000 +0300
@@ -122,4 +122,10 @@
     public boolean isRestackSupported() {
         return false;
     }
+
+    // The effects are not supported for system dialogs.
+    public void applyShape(sun.java2d.pipe.Region shape) {}
+    public void setOpacity(float opacity) {}
+    public void setOpaque(boolean isOpaque) {}
+    public void updateWindow(java.awt.image.BufferedImage backBuffer) {}
 }
                                     
2008-01-18
EVALUATION

Also we need not to clear the background when printing a translucent window. This is fixed in the WCanvasPeer.print() method (see the suggested fix).
                                     
2008-01-18



Hardware and Software, Engineered to Work Together