< prev index next >

src/share/classes/java/awt/Window.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

@@ -293,20 +293,20 @@
      * @see Dialog#shouldBlock
      */
     transient boolean isInShow = false;
 
     /*
-     * Opacity level of the window
+     * The opacity level of the window
      *
      * @see #setOpacity(float)
      * @see #getOpacity()
      * @since 1.7
      */
     private float opacity = 1.0f;
 
     /*
-     * The shape assigned to this window. This field is set to null if
+     * The shape assigned to this window. This field is set to {@code null} if
      * no shape is set (rectangular window).
      *
      * @see #getShape()
      * @see #setShape(Shape)
      * @since 1.7

@@ -385,12 +385,12 @@
                 window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
                                                opaque ? 255 : 0));
                 */
                 window.setOpaque(opaque);
             }
-            public void updateWindow(Window window, BufferedImage backBuffer) {
-                window.updateWindow(backBuffer);
+            public void updateWindow(Window window) {
+                window.updateWindow();
             }
 
             public void setLWRequestStatus(Window changed, boolean status) {
                 changed.syncLWRequests = status;
             }

@@ -3382,31 +3382,36 @@
      * JavaDoc
      */
 /*
     @Override
     public void setBackground(Color bgColor) {
+        Color oldBg = getBackground();
+        super.setBackground(bgColor);
+        if (oldBg != null && oldBg.equals(bgColor)) {
+            return;
+        }
+        int oldAlpha = oldBg != null ? oldBg.getAlpha() : 255;
         int alpha = bgColor.getAlpha();
-        if (alpha < 255) { // non-opaque window
+        if ((oldAlpha == 255) && (alpha < 255)) { // non-opaque window
             GraphicsConfiguration gc = getGraphicsConfiguration();
             GraphicsDevice gd = gc.getDevice();
             if (gc.getDevice().getFullScreenWindow() == this) {
-                throw new IllegalArgumentException(
+                throw new IllegalComponentStateException(
                     "Making full-screen window non opaque is not supported.");
             }
             if (!gc.isTranslucencyCapable()) {
                 GraphicsConfiguration capableGC = gd.getTranslucencyCapableGC();
                 if (capableGC == null) {
-                    throw new IllegalArgumentException(
+                    throw new UnsupportedOperationException(
                         "PERPIXEL_TRANSLUCENT translucency is not supported");
                 }
-                // TODO: change GC
+                setGraphicsConfiguration(capableGC);
             }
             setLayersOpaque(this, false);
+        } else if ((oldAlpha < 255) && (alpha == 255)) {
+            setLayersOpaque(this, true);
         }
-
-        super.setBackground(bgColor);
-
         WindowPeer peer = (WindowPeer)getPeer();
         if (peer != null) {
             peer.setOpaque(alpha == 255);
         }
     }

@@ -3438,43 +3443,58 @@
                 peer.setOpaque(opaque);
             }
         }
     }
 
-    private void updateWindow(BufferedImage backBuffer) {
+    private void updateWindow() {
         synchronized (getTreeLock()) {
             WindowPeer peer = (WindowPeer)getPeer();
             if (peer != null) {
-                peer.updateWindow(backBuffer);
+                peer.updateWindow();
             }
         }
     }
 
     private static final Color TRANSPARENT_BACKGROUND_COLOR = new Color(0, 0, 0, 0);
 
+    /**
+     * {@inheritDoc}
+     *
+     * @since 1.7
+     */
+    @Override
+    public void paint(Graphics g) {
+        Color bgColor = getBackground();
+        if ((bgColor != null) && (bgColor.getAlpha() < 255)) {
+            Graphics gg = g.create();
+            try {
+                if (gg instanceof Graphics2D) {
+                    gg.setColor(bgColor);
+                    ((Graphics2D)gg).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
+                    gg.fillRect(0, 0, getWidth(), getHeight());
+                }
+            } finally {
+                gg.dispose();
+            }
+        }
+        super.paint(g);
+    }
+
     private static void setLayersOpaque(Component component, boolean isOpaque) {
         // Shouldn't use instanceof to avoid loading Swing classes
         //    if it's a pure AWT application.
         if (Component.doesImplement(component, "javax.swing.RootPaneContainer")) {
             javax.swing.RootPaneContainer rpc = (javax.swing.RootPaneContainer)component;
             javax.swing.JRootPane root = rpc.getRootPane();
             javax.swing.JLayeredPane lp = root.getLayeredPane();
             Container c = root.getContentPane();
             javax.swing.JComponent content =
                 (c instanceof javax.swing.JComponent) ? (javax.swing.JComponent)c : null;
-            javax.swing.JComponent gp =
-                (rpc.getGlassPane() instanceof javax.swing.JComponent) ?
-                (javax.swing.JComponent)rpc.getGlassPane() : null;
-            if (gp != null) {
-                gp.setDoubleBuffered(isOpaque);
-            }
             lp.setOpaque(isOpaque);
             root.setOpaque(isOpaque);
-            root.setDoubleBuffered(isOpaque); //XXX: the "white rect" workaround
             if (content != null) {
                 content.setOpaque(isOpaque);
-                content.setDoubleBuffered(isOpaque); //XXX: the "white rect" workaround
 
                 // Iterate down one level to see whether we have a JApplet
                 // (which is also a RootPaneContainer) which requires processing
                 int numChildren = content.getComponentCount();
                 if (numChildren > 0) {
< prev index next >