1 /*
   2  * Copyright (c) 2012, 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  * @bug 4697612 6244705
  27  * @author Peter Zhelezniakov
  28  * @library ../../regtesthelpers
  29  * @build Util
  30  * @run main bug4697612
  31  */
  32 import java.io.*;
  33 import java.awt.*;
  34 import java.awt.event.*;
  35 import javax.swing.*;
  36 
  37 import javax.swing.text.BadLocationException;
  38 
  39 public class bug4697612 {
  40 
  41     static final int FRAME_WIDTH = 300;
  42     static final int FRAME_HEIGHT = 300;
  43     static final int FONT_HEIGHT = 16;
  44     private static volatile int frameHeight;
  45     private static volatile int fontHeight;
  46     private static JFrame frame;
  47     private static JTextArea text;
  48     private static JScrollPane scroller;
  49 
  50     public static void main(String[] args) throws Throwable {
  51         Robot robot = new Robot();
  52         robot.setAutoDelay(100);
  53 
  54         SwingUtilities.invokeAndWait(new Runnable() {
  55 
  56             @Override
  57             public void run() {
  58                 createAndShowGUI();
  59             }
  60         });
  61 
  62         robot.waitForIdle();
  63 
  64         SwingUtilities.invokeAndWait(new Runnable() {
  65 
  66             @Override
  67             public void run() {
  68                 text.requestFocus();
  69             }
  70         });
  71 
  72         robot.waitForIdle();
  73 
  74         // 4697612: pressing PgDn + PgUp should not alter caret position
  75         Util.hitKeys(robot, KeyEvent.VK_HOME);
  76         Util.hitKeys(robot, KeyEvent.VK_PAGE_DOWN);
  77 
  78 
  79         int pos0 = getTextCaretPosition();
  80         int caretHeight = getTextCaretHeight();
  81         fontHeight = FONT_HEIGHT;
  82 
  83         // iterate two times, for different (even and odd) font height
  84         for (int i = 0; i < 2; i++) {
  85 
  86             SwingUtilities.invokeAndWait(new Runnable() {
  87 
  88                 public void run() {
  89                     text.setFont(text.getFont().deriveFont(fontHeight));
  90                 }
  91             });
  92 
  93             frameHeight = FRAME_HEIGHT;
  94 
  95             for (int j = 0; j < caretHeight; j++) {
  96                 SwingUtilities.invokeAndWait(new Runnable() {
  97 
  98                     public void run() {
  99                         frame.setSize(FRAME_WIDTH, frameHeight);
 100                     }
 101                 });
 102 
 103                 robot.waitForIdle();
 104 
 105                 Util.hitKeys(robot, KeyEvent.VK_PAGE_DOWN);
 106                 Util.hitKeys(robot, KeyEvent.VK_PAGE_UP);
 107                 robot.waitForIdle();
 108 
 109                 int pos = getTextCaretPosition();
 110                 if (pos0 != pos) {
 111                     throw new RuntimeException("Failed 4697612: PgDn & PgUp keys scroll by different amounts");
 112                 }
 113                 frameHeight++;
 114             }
 115             fontHeight++;
 116         }
 117 
 118 
 119         // 6244705: pressing PgDn at the very bottom should not scroll
 120         LookAndFeel laf = UIManager.getLookAndFeel();
 121         if (laf.getID().equals("Aqua")) {
 122             Util.hitKeys(robot, KeyEvent.VK_END);
 123         } else {
 124             Util.hitKeys(robot, KeyEvent.VK_CONTROL, KeyEvent.VK_END);
 125         }
 126 
 127         robot.waitForIdle();
 128 
 129         pos0 = getScrollerViewPosition();
 130         Util.hitKeys(robot, KeyEvent.VK_PAGE_DOWN);
 131         robot.waitForIdle();
 132 
 133         int pos = getScrollerViewPosition();
 134 
 135         if (pos0 != pos) {
 136             throw new RuntimeException("Failed 6244705: PgDn at the bottom causes scrolling");
 137         }
 138     }
 139 
 140     private static int getTextCaretPosition() throws Exception {
 141         final int[] result = new int[1];
 142         SwingUtilities.invokeAndWait(new Runnable() {
 143 
 144             @Override
 145             public void run() {
 146                 result[0] = text.getCaretPosition();
 147             }
 148         });
 149 
 150         return result[0];
 151     }
 152 
 153     private static int getTextCaretHeight() throws Exception {
 154         final int[] result = new int[1];
 155         SwingUtilities.invokeAndWait(new Runnable() {
 156 
 157             @Override
 158             public void run() {
 159                 try {
 160                     int pos0 = text.getCaretPosition();
 161                     Rectangle dotBounds = text.modelToView(pos0);
 162                     result[0] = dotBounds.height;
 163                 } catch (BadLocationException ex) {
 164                     throw new RuntimeException(ex);
 165                 }
 166             }
 167         });
 168 
 169         return result[0];
 170     }
 171 
 172     private static int getScrollerViewPosition() throws Exception {
 173         final int[] result = new int[1];
 174         SwingUtilities.invokeAndWait(new Runnable() {
 175 
 176             @Override
 177             public void run() {
 178                 result[0] = scroller.getViewport().getViewPosition().y;
 179             }
 180         });
 181 
 182         return result[0];
 183     }
 184 
 185     private static void createAndShowGUI() {
 186         frame = new JFrame();
 187         frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
 188         frame.setPreferredSize(new Dimension(FRAME_WIDTH, FRAME_HEIGHT));
 189         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 190 
 191         text = new JTextArea();
 192         try {
 193             InputStream is =
 194                     bug4697612.class.getResourceAsStream("bug4697612.txt");
 195             text.read(new InputStreamReader(is), null);
 196         } catch (IOException e) {
 197             throw new Error(e);
 198         }
 199 
 200         scroller = new JScrollPane(text);
 201 
 202         frame.getContentPane().add(scroller);
 203 
 204         frame.pack();
 205         frame.setVisible(true);
 206     }
 207 }