1 /*
   2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.awt.AlphaComposite;
  25 import java.awt.Color;
  26 import java.awt.Graphics;
  27 import java.awt.Graphics2D;
  28 import java.awt.Rectangle;
  29 import java.awt.Robot;
  30 import java.awt.Window;
  31 import java.awt.image.BufferedImage;
  32 import java.util.concurrent.Callable;
  33 
  34 import javax.swing.JFrame;
  35 import javax.swing.JMenuItem;
  36 import javax.swing.JPanel;
  37 import javax.swing.JPopupMenu;
  38 import javax.swing.SwingUtilities;
  39 
  40 /*
  41    @test
  42    @key headful
  43    @bug 7156657 8186617 8171381
  44    @summary Version 7 doesn't support translucent popup menus against a translucent window
  45    @library ../../regtesthelpers
  46 */
  47 public class bug7156657 {
  48     private static JFrame lowerFrame;
  49 
  50     private static JFrame frame;
  51 
  52     private static JPopupMenu popupMenu;
  53 
  54     public static void main(String[] args) throws Exception {
  55         final Robot robot = new Robot();
  56 
  57         Boolean skipTest = Util.invokeOnEDT(new Callable<Boolean>() {
  58             @Override
  59             public Boolean call() throws Exception {
  60                 frame = createFrame();
  61                 if (!frame.getGraphicsConfiguration().isTranslucencyCapable()) {
  62                     System.out.println("Translucency is not supported, the test skipped");
  63 
  64                     return true;
  65                 }
  66 
  67                 lowerFrame = createFrame();
  68                 lowerFrame.getContentPane().setBackground(Color.RED);
  69                 lowerFrame.setVisible(true);
  70 
  71                 popupMenu = new JPopupMenu();
  72                 popupMenu.setOpaque(false);
  73                 popupMenu.add(new TransparentMenuItem("1111"));
  74                 popupMenu.add(new TransparentMenuItem("2222"));
  75                 popupMenu.add(new TransparentMenuItem("3333"));
  76 
  77                 setOpaque(frame, false);
  78                 JPanel pnContent = new JPanel();
  79                 pnContent.setBackground(new Color(255, 255, 255, 128));
  80                 frame.add(pnContent);
  81                 frame.setVisible(true);
  82 
  83                 return false;
  84             }
  85         });
  86 
  87         if (skipTest) {
  88             return;
  89         }
  90 
  91         robot.waitForIdle();
  92 
  93         SwingUtilities.invokeAndWait(new Runnable() {
  94             @Override
  95             public void run() {
  96                 popupMenu.show(frame, 0, 0);
  97             }
  98         });
  99 
 100         robot.waitForIdle();
 101 
 102         Rectangle popupRectangle = Util.invokeOnEDT(new Callable<Rectangle>() {
 103             @Override
 104             public Rectangle call() throws Exception {
 105                 return popupMenu.getBounds();
 106             }
 107         });
 108 
 109         BufferedImage redBackgroundCapture = robot.createScreenCapture(popupRectangle);
 110 
 111         SwingUtilities.invokeAndWait(new Runnable() {
 112             @Override
 113             public void run() {
 114                 lowerFrame.getContentPane().setBackground(Color.GREEN);
 115             }
 116         });
 117 
 118         robot.waitForIdle();
 119 
 120         BufferedImage greenBackgroundCapture = robot.createScreenCapture(popupRectangle);
 121 
 122         if (Util.compareBufferedImages(redBackgroundCapture, greenBackgroundCapture)) {
 123             throw new RuntimeException("The test failed");
 124         }
 125 
 126         SwingUtilities.invokeAndWait(new Runnable() {
 127             @Override
 128             public void run() {
 129                 popupMenu.setVisible(false);
 130                 frame.dispose();
 131                 lowerFrame.dispose();
 132             }
 133         });
 134     }
 135 
 136     public static void setOpaque(Window window, boolean opaque) {
 137         Color bg = window.getBackground();
 138         if (bg == null) {
 139             bg = new Color(0, 0, 0, 0);
 140         }
 141         window.setBackground(new Color(bg.getRed(), bg.getGreen(), bg.getBlue(),
 142                                        opaque ? 255 : 0));
 143     }
 144 
 145     private static JFrame createFrame() {
 146         JFrame result = new JFrame();
 147 
 148         result.setLocation(0, 0);
 149         result.setSize(400, 300);
 150         result.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 151         result.setUndecorated(true);
 152 
 153         return result;
 154     }
 155 
 156     private static class TransparentMenuItem extends JMenuItem {
 157         public TransparentMenuItem(String text) {
 158             super(text);
 159             setOpaque(false);
 160         }
 161 
 162         @Override
 163         public void paint(Graphics g) {
 164             Graphics2D g2 = (Graphics2D) g.create();
 165             g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
 166             super.paint(g2);
 167             g2.dispose();
 168         }
 169     }
 170 }