1 
   2 /*
   3  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /*
  26  * @test
  27  * @key headful
  28  * @bug 8025815
  29  * @summary Child FileDialog of modal dialog does not get focus on Gnome
  30  * @author Semyon Sadetsky
  31  */
  32 
  33 import javax.swing.*;
  34 import java.awt.*;
  35 import java.awt.event.*;
  36 import java.awt.image.BufferedImage;
  37 import java.lang.reflect.InvocationTargetException;
  38 import java.util.concurrent.TimeUnit;
  39 import java.util.concurrent.locks.Condition;
  40 import java.util.concurrent.locks.ReentrantLock;
  41 
  42 public class FileDialogModalFocusTest {
  43     public static void main(String[] args) throws Exception {
  44         Frame frame = new Frame();
  45         FileDialog fileDialog = new FileDialog((Frame) null);
  46         test(frame, fileDialog);
  47         frame = new Frame();
  48         fileDialog = new FileDialog(frame);
  49         test(frame, fileDialog);
  50         System.out.println("ok");
  51     }
  52 
  53     private static void test(final Frame frame, final FileDialog fileDialog)
  54             throws InterruptedException, InvocationTargetException,
  55             AWTException {
  56         Button button = new Button();
  57         button.setBackground(Color.RED);
  58         button.addActionListener(new ActionListener() {
  59             @Override
  60             public void actionPerformed(ActionEvent e) {
  61                 fileDialog.setVisible(true);
  62             }
  63         });
  64         frame.add(button);
  65         frame.setSize(200, 200);
  66         EventQueue.invokeAndWait(new Runnable() {
  67             @Override
  68             public void run() {
  69                 frame.setVisible(true);
  70             }
  71         });
  72         Robot robot = new Robot();
  73         robot.setAutoDelay(200);
  74         robot.waitForIdle();
  75         Point point = button.getLocationOnScreen();
  76         point.translate(100, 100);
  77         robot.mouseMove(point.x, point.y);
  78         robot.mousePress(InputEvent.BUTTON1_MASK);
  79         robot.mouseRelease(InputEvent.BUTTON1_MASK);
  80         int delay = 0;
  81         while (frame.isFocused() && delay < 2000) {
  82             robot.delay(50);
  83             delay += 50;
  84         }
  85         ReentrantLock lock = new ReentrantLock();
  86         Condition condition = lock.newCondition();
  87         button.addComponentListener(new ComponentAdapter() {
  88             @Override
  89             public void componentResized(ComponentEvent e) {
  90                 lock.lock();
  91                 condition.signal();
  92                 lock.unlock();
  93             }
  94         });
  95         lock.lock();
  96         EventQueue.invokeLater(new Runnable() {
  97             @Override
  98             public void run() {
  99                 frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
 100             }
 101         });
 102         condition.await(5, TimeUnit.SECONDS);
 103         lock.unlock();
 104         robot.delay(200);
 105         robot.waitForIdle();
 106         EventQueue.invokeAndWait(new Runnable() {
 107             @Override
 108             public void run() {
 109                 button.requestFocus();
 110                 Point p = new Point(button.getWidth() - 10, button.getHeight() - 10);
 111                 SwingUtilities.convertPointToScreen(p, button);
 112                 robot.mouseMove(p.x, p.y);
 113                 robot.mousePress(InputEvent.BUTTON1_MASK);
 114                 robot.mouseRelease(InputEvent.BUTTON1_MASK);
 115             }
 116         });
 117         robot.waitForIdle();
 118         Point p = new Point(100, 100);
 119         SwingUtilities.convertPointToScreen(p, button);
 120         BufferedImage image = robot.createScreenCapture(
 121                 new Rectangle(p,
 122                         new Dimension(button.getWidth() - 200,
 123                                 button.getHeight() - 200)));
 124         boolean found = false;
 125         for (int x = 0; x < image.getWidth(); x+=50) {
 126             for (int y = 0; y < image.getHeight(); y+=50) {
 127                 if( (image.getRGB(x, y) & 0x00FFFF) != 0 ) {
 128                     found = true;
 129                     break;
 130                 };
 131             }
 132         }
 133         frame.dispose();
 134         robot.waitForIdle();
 135         fileDialog.dispose();
 136         if(!found) {
 137             throw new RuntimeException("file chooser is underneath");
 138         }
 139     }
 140 }