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