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