1 /*
   2  * Copyright (c) 2018, 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 import javax.swing.*;
  25 import java.awt.*;
  26 import java.awt.event.InputEvent;
  27 import java.awt.image.BufferedImage;
  28 
  29 /**
  30  * @test
  31  * @bug 8188081 8194135
  32  * @summary  The content in textArea can not be pasted after clicking "Copy" button.
  33  * @requires os.family == "linux"
  34  * @key headful
  35  * @run main MultiSelectionTest
  36  */
  37 
  38 public class MultiSelectionTest {
  39 
  40     private static JTextField field1;
  41     private static JTextField field2;
  42     private static JFrame frame;
  43     private static Rectangle bounds;
  44     private static JMenu menu;
  45     private static JTextField anotherWindow;
  46     private static Point menuLoc;
  47     private static JFrame frame2;
  48 
  49     public static void main(String[] args) throws Exception {
  50         SwingUtilities.invokeAndWait(() -> {
  51             frame = new JFrame();
  52             field1 = new JTextField("field1                       ");
  53             field2 = new JTextField("field2                       ");
  54             field1.setEditable(false);
  55             field2.setEditable(false);
  56             frame.getContentPane().setLayout(new FlowLayout());
  57             frame.getContentPane().add(field1);
  58             frame.getContentPane().add(field2);
  59             JMenuBar menuBar = new JMenuBar();
  60             menu = new JMenu("menu");
  61             menu.add(new JMenuItem("item"));
  62             menuBar.add(menu);
  63             frame.setJMenuBar(menuBar);
  64             frame.pack();
  65             frame.setVisible(true);
  66         });
  67 
  68         Robot robot = new Robot();
  69         robot.waitForIdle();
  70         robot.delay(200);
  71         SwingUtilities.invokeAndWait(() -> {
  72             bounds = field2.getBounds();
  73             bounds.setLocation(field2.getLocationOnScreen());
  74         });
  75         BufferedImage nosel = robot.createScreenCapture(bounds);
  76 
  77         SwingUtilities.invokeAndWait(field2::requestFocus);
  78         SwingUtilities.invokeAndWait(field2::selectAll);
  79         robot.waitForIdle();
  80         robot.delay(200);
  81         BufferedImage sel = robot.createScreenCapture(bounds);
  82 
  83         SwingUtilities.invokeAndWait(() -> {
  84             menuLoc = menu.getLocationOnScreen();
  85             menuLoc.translate(10, 10);
  86         });
  87         robot.mouseMove(menuLoc.x, menuLoc.y);
  88         robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
  89         robot.delay(50);
  90         robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
  91         robot.waitForIdle();
  92         robot.delay(200);
  93         if (!biEqual(robot.createScreenCapture(bounds), sel)) {
  94             throw new RuntimeException("Test fails: menu hides selection");
  95         }
  96 
  97         SwingUtilities.invokeAndWait(
  98                       MenuSelectionManager.defaultManager()::clearSelectedPath);
  99         SwingUtilities.invokeAndWait(field1::requestFocus);
 100         robot.waitForIdle();
 101         robot.delay(200);
 102         if (!biEqual(robot.createScreenCapture(bounds), sel)) {
 103             throw new RuntimeException(
 104                     "Test fails: focus lost hides single selection");
 105         }
 106 
 107         SwingUtilities.invokeAndWait(field1::selectAll);
 108         robot.waitForIdle();
 109         robot.delay(200);
 110         if (!biEqual(robot.createScreenCapture(bounds), nosel)) {
 111             throw new RuntimeException(
 112                     "Test fails: focus lost doesn't hide selection upon multi selection");
 113         }
 114 
 115         SwingUtilities.invokeAndWait(field2::requestFocus);
 116         robot.waitForIdle();
 117         robot.delay(200);
 118         if (!biEqual(robot.createScreenCapture(bounds), sel)) {
 119             throw new RuntimeException(
 120                     "Test fails: focus gain hides selection upon multi selection");
 121         }
 122 
 123         SwingUtilities.invokeAndWait(field2::requestFocus);
 124         robot.waitForIdle();
 125         SwingUtilities.invokeAndWait(() ->{
 126             frame2 = new JFrame();
 127             Point loc = frame.getLocationOnScreen();
 128             loc.translate(0, frame.getHeight());
 129             frame2.setLocation(loc);
 130             anotherWindow = new JTextField("textField3");
 131             frame2.add(anotherWindow);
 132             frame2.pack();
 133             frame2.setVisible(true);
 134         });
 135         robot.waitForIdle();
 136         SwingUtilities.invokeAndWait(anotherWindow::requestFocus);
 137         robot.waitForIdle();
 138         robot.delay(200);
 139         if (biEqual(robot.createScreenCapture(bounds), nosel)) {
 140             throw new RuntimeException(
 141                     "Test fails: switch window hides selection");
 142         }
 143 
 144         SwingUtilities.invokeAndWait(anotherWindow::selectAll);
 145         robot.waitForIdle();
 146         robot.delay(200);
 147         if (biEqual(robot.createScreenCapture(bounds), sel)) {
 148             throw new RuntimeException(
 149                 "Test fails: selection ownership is lost selection is shown");
 150         }
 151 
 152         SwingUtilities.invokeLater(frame2::dispose);
 153         SwingUtilities.invokeLater(frame::dispose);
 154     }
 155 
 156     static boolean biEqual(BufferedImage i1, BufferedImage i2) {
 157         if (i1.getWidth() == i2.getWidth() &&
 158                                          i1.getHeight() == i2.getHeight()) {
 159             for (int x = 0; x < i1.getWidth(); x++) {
 160                 for (int y = 0; y < i1.getHeight(); y++) {
 161                     if (i1.getRGB(x, y) != i2.getRGB(x, y)) {
 162                         return false;
 163                     }
 164                 }
 165             }
 166             return true;
 167         }
 168         return false;
 169     }
 170 }