1 /*
   2  * Copyright (c) 1999, 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  * @summary Make sure that on changing state of Undecorated Frame,
  28  *          all the components on it are repainted correctly
  29  * @author Jitender(jitender.singh@eng.sun.com) area=AWT
  30  * @author yan
  31  * @library ../../../../lib/client
  32  * @build ExtendedRobot
  33  * @run main RepaintTest
  34  */
  35 
  36 import java.awt.*;
  37 import java.awt.event.*;
  38 import javax.swing.JFrame;
  39 import javax.swing.JButton;
  40 import javax.swing.JTextField;
  41 import javax.swing.JPanel;
  42 import java.io.*;
  43 import java.awt.image.*;
  44 
  45 public class RepaintTest {
  46     private static int delay = 150;
  47 
  48     private Frame frame;
  49     private Container panel1, panel2;
  50     private Component button;
  51     private Component textField;
  52     private ExtendedRobot robot;
  53     private Object buttonLock = new Object();
  54     private boolean passed = true;
  55     private boolean buttonClicked = false;
  56     private int MAX_TOLERANCE_LEVEL = 10;
  57 
  58     public static void main(String[] args) {
  59         RepaintTest test = new RepaintTest();
  60         test.doTest(false);
  61         try {
  62             Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait(new Runnable() {
  63                 public void run() {
  64                     test.frame.dispose();
  65                 }
  66             });
  67         } catch (Exception e) {
  68             e.printStackTrace();
  69             throw new RuntimeException("Unexpected Exception occured");
  70         }
  71         test.doTest(true);
  72         try {
  73             Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait(new Runnable() {
  74                 public void run() {
  75                     test.frame.dispose();
  76                 }
  77             });
  78         } catch (Exception e) {
  79             e.printStackTrace();
  80             throw new RuntimeException("Unexpected Exception occured");
  81         }
  82     }
  83 
  84     /**
  85      * Do screen capture and save it as image
  86      */
  87     private static void captureScreenAndSave() {
  88 
  89         try {
  90             Robot robot = new Robot();
  91             Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
  92             Rectangle rectangle = new Rectangle(0, 0, screenSize.width, screenSize.height);
  93             System.out.println("About to screen capture - " + rectangle);
  94             BufferedImage image = robot.createScreenCapture(rectangle);
  95             javax.imageio.ImageIO.write(image, "jpg", new File("ScreenImage.jpg"));
  96             robot.delay(3000);
  97         } catch (Throwable t) {
  98             System.out.println("WARNING: Exception thrown while screen capture!");
  99             t.printStackTrace();
 100         }
 101     }
 102 
 103     private void initializeGUI(boolean swingControl) {
 104         frame = swingControl ? new JFrame() : new Frame();
 105         frame.setLayout(new BorderLayout());
 106 
 107         frame.setSize(300, 300);
 108         frame.setUndecorated(true);
 109 
 110         button = createButton(swingControl, (swingControl ? "Swing Button" : "AWT Button"));
 111         textField = swingControl ? new JTextField("TextField") : new TextField("TextField");
 112         panel1 = swingControl ? new JPanel() : new Panel();
 113         panel2 = swingControl ? new JPanel() : new Panel();
 114         panel1.add(button);
 115         panel2.add(textField);
 116         frame.add(panel2, BorderLayout.SOUTH);
 117         frame.add(panel1, BorderLayout.NORTH);
 118 
 119         frame.setBackground(Color.green);
 120         frame.setVisible(true);
 121         frame.toFront();
 122     }
 123     private Component createButton(boolean swingControl, String txt) {
 124         if(swingControl) {
 125             JButton jbtn = new JButton(txt);
 126             jbtn.addActionListener(new ActionListener() {
 127                 public void actionPerformed(ActionEvent e) {
 128                     buttonClicked = true;
 129                     synchronized (buttonLock) {
 130                         try {
 131                             buttonLock.notifyAll();
 132                         } catch (Exception ex) {
 133                             ex.printStackTrace();
 134                         }
 135                     }
 136                 }
 137             });
 138             return jbtn;
 139         }else {
 140             Button btn = new Button(txt);
 141             btn.addActionListener(new ActionListener() {
 142                 public void actionPerformed(ActionEvent e) {
 143                     buttonClicked = true;
 144                     synchronized (buttonLock) {
 145                         try {
 146                             buttonLock.notifyAll();
 147                         } catch (Exception ex) {
 148                             ex.printStackTrace();
 149                         }
 150                     }
 151                 }
 152             });
 153             return btn;
 154         }
 155     }
 156 
 157     public void doTest(boolean swingControl) {
 158         try {
 159             Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait(new Runnable() {
 160                 public void run() {
 161                     initializeGUI(swingControl);
 162                 }
 163             });
 164         } catch (Exception e) {
 165             e.printStackTrace();
 166             throw new RuntimeException("Interrupted or unexpected Exception occured");
 167         }
 168         try {
 169             robot = new ExtendedRobot();
 170             robot.waitForIdle(1000);
 171         } catch (Exception e) {
 172             e.printStackTrace();
 173             throw new RuntimeException("Cannot create robot");
 174         }
 175 
 176         robot.mouseMove(button.getLocationOnScreen().x + button.getSize().width / 2,
 177                         button.getLocationOnScreen().y + button.getSize().height / 2);
 178         robot.waitForIdle(delay);
 179         robot.mousePress(InputEvent.BUTTON1_MASK);
 180         robot.waitForIdle(delay);
 181         robot.mouseRelease(InputEvent.BUTTON1_MASK);
 182 
 183         if (! buttonClicked) {
 184             synchronized (buttonLock) {
 185                 try {
 186                     buttonLock.wait(delay * 10);
 187                 } catch (Exception e) {
 188                 }
 189             }
 190         }
 191         if (! buttonClicked) {
 192             passed = false;
 193             System.err.println("ActionEvent not triggered when " +
 194                     "button is clicked!");
 195             throw new RuntimeException("ActionEvent not triggered");
 196         }
 197 
 198         robot.waitForIdle(delay * 5); // Need to wait until look of the button
 199                                       // returns to normal undepressed
 200         passed = paintAndRepaint(button, (swingControl? "J": "")+"Button");
 201         if( !paintAndRepaint(button, (swingControl? "J": "")+"TextField") ) {
 202             passed = false;
 203         }
 204         if(!passed) {
 205             throw new RuntimeException("Test failed");
 206         }
 207     }
 208     private boolean paintAndRepaint(Component comp, String prefix) {
 209         //Capture the component & compare it's dimensions
 210         //before iconifying & after frame comes back from
 211         //iconified to normal state
 212         System.out.println("paintAndRepaint "+prefix);
 213         Point p = comp.getLocationOnScreen();
 214         Rectangle bRect = new Rectangle((int)p.getX(), (int)p.getY(),
 215                                                 comp.getWidth(), comp.getHeight());
 216         BufferedImage capturedImage = robot.createScreenCapture(bRect);
 217 
 218         try {
 219             Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait(new Runnable() {
 220                 public void run() {
 221                     frame.setExtendedState(Frame.ICONIFIED);
 222                 }
 223             });
 224         } catch (Exception e) {
 225             e.printStackTrace();
 226             throw new RuntimeException("Exception while setting extended state ICONIFIED");
 227         }
 228         robot.waitForIdle(delay * 5);
 229         try {
 230             Toolkit.getDefaultToolkit().getSystemEventQueue().invokeAndWait(new Runnable() {
 231                 public void run() {
 232                     frame.setExtendedState(Frame.NORMAL);
 233                     frame.toFront();
 234                 }
 235             });
 236         } catch (Exception e) {
 237             e.printStackTrace();
 238             throw new RuntimeException("Exception while setting extended state NORMAL");
 239         }
 240         robot.waitForIdle(delay * 5);
 241 
 242         if (! p.equals(comp.getLocationOnScreen())) {
 243             passed = false;
 244             System.err.println("FAIL: Frame or component did not get positioned in the same place");
 245         }
 246 
 247         p = comp.getLocationOnScreen();
 248         bRect = new Rectangle((int)p.getX(), (int)p.getY(),
 249                                   comp.getWidth(), comp.getHeight());
 250         BufferedImage capturedImage2 = robot.createScreenCapture(bRect);
 251 
 252         if (! compareImages(capturedImage, capturedImage2)) {
 253             passed = false;
 254             try {
 255                 javax.imageio.ImageIO.write(capturedImage, "jpg", new File(
 256                                    prefix+"BeforeMinimize.jpg"));
 257                 javax.imageio.ImageIO.write(capturedImage2, "jpg", new File(
 258                                    prefix+"AfterMinimize.jpg"));
 259             } catch (Exception e) {
 260                 e.printStackTrace();
 261             }
 262 
 263             System.err.println("FAIL: The frame or component did not get repainted correctly");
 264         }
 265         return passed;
 266     }
 267 
 268     //method for comparing two images
 269     public boolean compareImages(BufferedImage capturedImg, BufferedImage realImg) {
 270         int capturedPixels[], realPixels[];
 271         int imgWidth, imgHeight;
 272         boolean comparison = true;
 273         int toleranceLevel = 0;
 274 
 275         imgWidth = capturedImg.getWidth(null);
 276         imgHeight = capturedImg.getHeight(null);
 277         capturedPixels = new int[imgWidth * imgHeight];
 278         realPixels = new int[imgWidth * imgHeight];
 279 
 280         try {
 281             PixelGrabber pgCapturedImg = new PixelGrabber(capturedImg, 0, 0,
 282                               imgWidth, imgHeight, capturedPixels, 0, imgWidth);
 283             pgCapturedImg.grabPixels();
 284 
 285             PixelGrabber pgRealImg = new PixelGrabber(realImg, 0, 0,
 286                               imgWidth, imgHeight, realPixels, 0, imgWidth);
 287             pgRealImg.grabPixels();
 288 
 289             for(int i=0; i<(imgWidth * imgHeight); i++) {
 290                 if(capturedPixels[i] != realPixels[i]) {
 291                     toleranceLevel++;
 292                 }
 293             }
 294 
 295             if (toleranceLevel > MAX_TOLERANCE_LEVEL) {
 296                 comparison = false;
 297             }
 298         } catch(Exception ie) {
 299             ie.printStackTrace();
 300             comparison = false;
 301         }
 302         return comparison;
 303     }
 304 }