1 /*
   2  * Copyright (c) 2016, 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 /*
  25   @test
  26   @bug 8150176
  27   @author a.stepanov
  28   @summary Check if correct resolution variant is used
  29            for JOptionPane dialog icons.
  30   @library ../../../../lib/testlibrary/
  31   @build ExtendedRobot
  32   @run main/othervm/timeout=300 -Dsun.java2d.uiScale=1 MultiResolutionJOptionPaneIconTest
  33   @run main/othervm/timeout=300 -Dsun.java2d.uiScale=2 MultiResolutionJOptionPaneIconTest
  34 */
  35 
  36 import java.awt.*;
  37 import java.awt.event.*;
  38 import java.awt.geom.AffineTransform;
  39 import java.awt.image.*;
  40 import javax.swing.*;
  41 
  42 public class MultiResolutionJOptionPaneIconTest
  43         extends JFrame implements ActionListener {
  44 
  45     private final static Color C1X = Color.ORANGE, C2X = Color.CYAN;
  46 
  47     private final boolean isInternal;
  48 
  49     private volatile JDialog dialog;
  50     private volatile JInternalFrame frame;
  51 
  52     private final JDesktopPane parentPane;
  53     private final JButton run;
  54 
  55     private final ExtendedRobot robot;
  56 
  57     private static BufferedImage getSquare(int sz, Color c) {
  58 
  59         BufferedImage img = new BufferedImage(sz, sz, BufferedImage.TYPE_INT_RGB);
  60         Graphics g = img.getGraphics();
  61         g.setColor(c);
  62         g.fillRect(0, 0, sz, sz);
  63         return img;
  64     }
  65 
  66     private static Icon getIcon() {
  67 
  68         BaseMultiResolutionImage mri = new BaseMultiResolutionImage(
  69             new BufferedImage[]{getSquare(16, C1X), getSquare(32, C2X)});
  70         return new ImageIcon(mri);
  71     }
  72 
  73     public MultiResolutionJOptionPaneIconTest(boolean internal,
  74                 UIManager.LookAndFeelInfo lf) throws Exception {
  75 
  76         UIManager.setLookAndFeel(lf.getClassName());
  77 
  78         isInternal = internal;
  79 
  80         robot = new ExtendedRobot();
  81         robot.setAutoDelay(50);
  82 
  83         parentPane = new JDesktopPane();
  84         run = new JButton("run");
  85         SwingUtilities.invokeLater(this::UI);
  86     }
  87 
  88     private void UI() {
  89 
  90         setLayout(new BorderLayout());
  91         add(parentPane, BorderLayout.CENTER);
  92 
  93         run.addActionListener(this);
  94         add(run, BorderLayout.SOUTH);
  95         setUndecorated(true);
  96         setSize(400, 300);
  97         setLocation(50, 50);
  98         setVisible(true);
  99     }
 100 
 101     public void doTest() throws Exception {
 102 
 103         try {
 104 
 105             robot.waitForIdle(1000);
 106             clickButton(robot);
 107             robot.waitForIdle(1000);
 108 
 109             Component c = isInternal ?
 110                 frame.getContentPane() : dialog.getContentPane();
 111 
 112             System.out.println("\ncheck " + (isInternal ? "internal frame" :
 113                 "dialog") + " icon:");
 114 
 115             Point pt = c.getLocationOnScreen();
 116             checkColors(pt.x, c.getWidth(), pt.y, c.getHeight());
 117 
 118             robot.waitForIdle();
 119 
 120             if (isInternal) {
 121                 SwingUtilities.invokeAndWait(() -> { frame.dispose(); });
 122             } else {
 123                 SwingUtilities.invokeAndWait(() -> { dialog.dispose(); });
 124             }
 125             robot.waitForIdle();
 126 
 127             System.out.println("ok");
 128 
 129         } finally { dispose(); }
 130     }
 131 
 132     private void checkColors(int x0, int w, int y0, int h) {
 133 
 134         Color
 135             expected   = is2x() ? C2X : C1X,
 136             unexpected = is2x() ? C1X : C2X;
 137 
 138         for (int y = y0; y < y0 + h; y += 5) {
 139             for (int x = x0; x < x0 + w; x += 5) {
 140 
 141                 Color c = robot.getPixelColor(x, y);
 142                 if (c.equals(unexpected)) {
 143                     throw new RuntimeException(
 144                         "invalid color was found, test failed");
 145                 } else if (c.equals(expected)) { return; }
 146             }
 147         }
 148 
 149         // no icon found at all
 150         throw new RuntimeException("the icon wasn't found");
 151     }
 152 
 153     private void showDialogOrFrame() {
 154 
 155         JOptionPane pane = new JOptionPane("",
 156                                            JOptionPane.DEFAULT_OPTION,
 157                                            JOptionPane.INFORMATION_MESSAGE,
 158                                            getIcon());
 159 
 160         pane.setOptions(new Object[]{});
 161 
 162         if (isInternal) {
 163             frame = pane.createInternalFrame(parentPane, "");
 164             frame.setLocation(0, 0);
 165             frame.setVisible(true);
 166         } else {
 167             dialog = pane.createDialog(parentPane, "");
 168             dialog.setVisible(true);
 169         }
 170     }
 171 
 172     public void clickButton(ExtendedRobot robot) {
 173 
 174         Point pt = run.getLocationOnScreen();
 175         robot.mouseMove(pt.x + run.getWidth() / 2, pt.y + run.getHeight() / 2);
 176         robot.waitForIdle();
 177         robot.click();
 178     }
 179 
 180     @Override
 181     public void actionPerformed(ActionEvent event) { showDialogOrFrame(); }
 182 
 183 
 184 
 185     private static boolean is2x() {
 186 
 187         AffineTransform tr = GraphicsEnvironment.getLocalGraphicsEnvironment().
 188             getDefaultScreenDevice().getDefaultConfiguration().
 189             getDefaultTransform();
 190         return (Math.min(tr.getScaleX(), tr.getScaleY()) > 1.001);
 191     }
 192 
 193 
 194     public static void main(String[] args) throws Exception {
 195 
 196         // TODO: remove is2x() check after JDK-8150844 fix
 197         String scale = System.getProperty("sun.java2d.uiScale");
 198         if (is2x() != "2".equals(scale)) { return; }
 199 
 200         for (UIManager.LookAndFeelInfo LF: UIManager.getInstalledLookAndFeels()) {
 201             System.out.println("\nL&F: " + LF.getName());
 202             (new MultiResolutionJOptionPaneIconTest(false, LF)).doTest();
 203             (new MultiResolutionJOptionPaneIconTest(true , LF)).doTest();
 204         }
 205     }
 206 }