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 /* @test
  25  * @bug 8146321 8151282
  26  * @summary verifies JInternalFrame Icon and ImageIcon
  27  * @library ../../regtesthelpers
  28  * @build Util
  29  * @run main JInternalFrameIconTest
  30  */
  31 import java.awt.BorderLayout;
  32 import java.awt.Component;
  33 import java.awt.Graphics;
  34 import java.awt.Point;
  35 import java.awt.Rectangle;
  36 import java.awt.Robot;
  37 import java.awt.image.BufferedImage;
  38 import javax.swing.Icon;
  39 import javax.swing.ImageIcon;
  40 import javax.swing.JDesktopPane;
  41 import javax.swing.JFrame;
  42 import javax.swing.JInternalFrame;
  43 import javax.swing.SwingUtilities;
  44 import javax.swing.UIManager;
  45 import javax.swing.UnsupportedLookAndFeelException;
  46 
  47 public class JInternalFrameIconTest {
  48 
  49     private static JFrame frame;
  50     private static JDesktopPane desktopPane;
  51     private static JInternalFrame internalFrame;
  52     private static ImageIcon titleImageIcon;
  53     private static Icon titleIcon;
  54     private static BufferedImage imageIconImage;
  55     private static BufferedImage iconImage;
  56     private static Robot robot;
  57     private static volatile String errorString = "";
  58 
  59 
  60     public static void main(String[] args) throws Exception {
  61         robot = new Robot();
  62         robot.delay(2000);
  63         UIManager.LookAndFeelInfo[] lookAndFeelArray
  64                 = UIManager.getInstalledLookAndFeels();
  65         for (UIManager.LookAndFeelInfo lookAndFeelItem : lookAndFeelArray) {
  66             executeCase(lookAndFeelItem.getClassName());
  67         }
  68         if (!"".equals(errorString)) {
  69             throw new RuntimeException("Error Log:\n" + errorString);
  70         }
  71 
  72     }
  73 
  74     private static void executeCase(String lookAndFeelString) throws Exception {
  75         if (tryLookAndFeel(lookAndFeelString)) {
  76             createImageIconUI(lookAndFeelString);
  77             robot.delay(1000);
  78             getImageIconBufferedImage();
  79             robot.delay(1000);
  80             cleanUp();
  81             robot.waitForIdle();
  82 
  83             createIconUI(lookAndFeelString);
  84             robot.delay(1000);
  85             getIconBufferedImage();
  86             robot.delay(1000);
  87             cleanUp();
  88             robot.waitForIdle();
  89 
  90             testIfSame(lookAndFeelString);
  91             robot.waitForIdle();
  92         }
  93 
  94     }
  95 
  96     private static void createImageIconUI(final String lookAndFeelString)
  97             throws Exception {
  98         SwingUtilities.invokeAndWait(new Runnable() {
  99             @Override
 100             public void run() {
 101                 desktopPane = new JDesktopPane();
 102                 internalFrame = new JInternalFrame();
 103                 frame = new JFrame();
 104                 internalFrame.setTitle(lookAndFeelString);
 105                 titleImageIcon = new ImageIcon() {
 106                     @Override
 107                     public int getIconWidth() {
 108                         return 16;
 109                     }
 110 
 111                     @Override
 112                     public int getIconHeight() {
 113                         return 16;
 114                     }
 115 
 116                     @Override
 117                     public void paintIcon(
 118                             Component c, Graphics g, int x, int y) {
 119                         g.setColor(java.awt.Color.black);
 120                         g.fillRect(x, y, 16, 16);
 121                     }
 122                 };
 123                 internalFrame.setFrameIcon(titleImageIcon);
 124                 internalFrame.setSize(500, 200);
 125                 internalFrame.setVisible(true);
 126                 desktopPane.add(internalFrame);
 127 
 128                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 129                 frame.getContentPane().setLayout(new BorderLayout());
 130                 frame.getContentPane().add(desktopPane, "Center");
 131                 frame.setSize(500, 500);
 132                 frame.setLocationRelativeTo(null);
 133                 frame.setVisible(true);
 134                 frame.toFront();
 135             }
 136         });
 137     }
 138 
 139     private static void createIconUI(final String lookAndFeelString)
 140             throws Exception {
 141         SwingUtilities.invokeAndWait(new Runnable() {
 142             @Override
 143             public void run() {
 144                 desktopPane = new JDesktopPane();
 145                 internalFrame = new JInternalFrame();
 146                 frame = new JFrame();
 147                 internalFrame.setTitle(lookAndFeelString);
 148                 titleIcon = new Icon() {
 149                     @Override
 150                     public int getIconWidth() {
 151                         return 16;
 152                     }
 153 
 154                     @Override
 155                     public int getIconHeight() {
 156                         return 16;
 157                     }
 158 
 159                     @Override
 160                     public void paintIcon(
 161                             Component c, Graphics g, int x, int y) {
 162                         g.setColor(java.awt.Color.black);
 163                         g.fillRect(x, y, 16, 16);
 164                     }
 165                 };
 166                 internalFrame.setFrameIcon(titleIcon);
 167                 internalFrame.setSize(500, 200);
 168                 internalFrame.setVisible(true);
 169                 desktopPane.add(internalFrame);
 170 
 171                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 172                 frame.getContentPane().setLayout(new BorderLayout());
 173                 frame.getContentPane().add(desktopPane, "Center");
 174                 frame.setSize(500, 500);
 175                 frame.setLocationRelativeTo(null);
 176                 frame.setVisible(true);
 177                 frame.toFront();
 178             }
 179         });
 180     }
 181 
 182     private static void getImageIconBufferedImage() throws Exception {
 183         Point point = internalFrame.getLocationOnScreen();
 184         Rectangle rect = internalFrame.getBounds();
 185         Rectangle captureRect = new Rectangle(
 186                 point.x + internalFrame.getInsets().left,
 187                 point.y,
 188                 rect.width,
 189                 internalFrame.getInsets().top);
 190         imageIconImage
 191                 = robot.createScreenCapture(captureRect);
 192     }
 193 
 194     private static void getIconBufferedImage() throws Exception {
 195         Point point = internalFrame.getLocationOnScreen();
 196         Rectangle rect = internalFrame.getBounds();
 197         Rectangle captureRect = new Rectangle(
 198                 point.x + internalFrame.getInsets().left,
 199                 point.y,
 200                 rect.width,
 201                 internalFrame.getInsets().top);
 202         iconImage
 203                 = robot.createScreenCapture(captureRect);
 204     }
 205 
 206     private static void testIfSame(final String lookAndFeelString)
 207             throws Exception {
 208         if (!bufferedImagesEqual(imageIconImage, iconImage)) {
 209             String error ="[" + lookAndFeelString
 210                     + "] : ERROR: icon and imageIcon not same.";
 211             errorString += error;
 212             System.err.println(error);
 213         } else {
 214             System.out.println("[" + lookAndFeelString
 215                     + "] : SUCCESS: icon and imageIcon same.");
 216         }
 217     }
 218 
 219     private static boolean bufferedImagesEqual(
 220             BufferedImage bufferedImage1, BufferedImage bufferedImage2) {
 221         boolean flag = true;
 222 
 223         if (bufferedImage1.getWidth() == bufferedImage2.getWidth()
 224                 && bufferedImage1.getHeight() == bufferedImage2.getHeight()) {
 225             final int colorTolerance = 25;
 226             final int mismatchTolerance = (int) (0.1
 227                     * bufferedImage1.getWidth() * bufferedImage1.getHeight());
 228             int mismatchCounter = 0;
 229             for (int x = 0; x < bufferedImage1.getWidth(); x++) {
 230                 for (int y = 0; y < bufferedImage1.getHeight(); y++) {
 231 
 232                     int color1 = bufferedImage1.getRGB(x, y);
 233                     int red1 = (color1 >> 16) & 0x000000FF;
 234                     int green1 = (color1 >> 8) & 0x000000FF;
 235                     int blue1 = (color1) & 0x000000FF;
 236 
 237                     int color2 = bufferedImage2.getRGB(x, y);
 238                     int red2 = (color2 >> 16) & 0x000000FF;
 239                     int green2 = (color2 >> 8) & 0x000000FF;
 240                     int blue2 = (color2) & 0x000000FF;
 241                     if (red1 != red2 || green1 != green2 || blue1 != blue2) {
 242                         ++mismatchCounter;
 243                         if ((Math.abs(red1 - red2) > colorTolerance)
 244                                 || (Math.abs(green1 - green2) > colorTolerance)
 245                                 || (Math.abs(blue1 - blue2) > colorTolerance)) {
 246 
 247                             flag = false;
 248                         }
 249                     }
 250                 }
 251             }
 252             if (mismatchCounter > mismatchTolerance) {
 253                 flag = false;
 254             }
 255         } else {
 256             System.err.println("ERROR: size is different");
 257             flag = false;
 258         }
 259         return flag;
 260     }
 261 
 262     private static void cleanUp() throws Exception {
 263         SwingUtilities.invokeAndWait(new Runnable() {
 264             @Override
 265             public void run() {
 266                 frame.dispose();
 267             }
 268         });
 269     }
 270 
 271     private static boolean tryLookAndFeel(String lookAndFeelString)
 272             throws Exception {
 273         //This test case is not applicable for Motif and gtk LAFs
 274         if(lookAndFeelString.contains("motif")
 275                 || lookAndFeelString.contains("gtk")) {
 276             return false;
 277         }
 278         try {
 279             UIManager.setLookAndFeel(
 280                     lookAndFeelString);
 281 
 282         } catch (UnsupportedLookAndFeelException
 283                 | ClassNotFoundException
 284                 | InstantiationException
 285                 | IllegalAccessException e) {
 286             return false;
 287         }
 288         return true;
 289     }
 290 }