blob: 3346071400396b12f164a121a59427b6938e374f [file] [log] [blame]
rupashka3bcc9e92011-03-03 17:47:41 +03001/*
kshefove57475e2013-02-13 19:06:31 +04002 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
rupashka3bcc9e92011-03-03 17:47:41 +03003 * 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
24import javax.swing.*;
25import java.awt.*;
kshefove57475e2013-02-13 19:06:31 +040026import java.awt.event.*;
rupashka3bcc9e92011-03-03 17:47:41 +030027import java.awt.image.BufferedImage;
rupashka42a48d92012-04-10 19:09:48 +030028import java.util.ArrayList;
rupashkab1c369f2011-03-14 15:01:53 +030029import java.util.LinkedList;
30import java.util.List;
rupashka42a48d92012-04-10 19:09:48 +030031import java.util.concurrent.Callable;
kshefove57475e2013-02-13 19:06:31 +040032import sun.swing.*;
rupashka3bcc9e92011-03-03 17:47:41 +030033
34/**
35 * <p>This class contains utilities useful for regression testing.
36 * <p>When using jtreg you would include this class via something like:
37 * <pre>
38 *
39 * @library ../../regtesthelpers
40 * @build Util
41 * </pre>
42 */
43
44public class Util {
45 /**
46 * Convert a rectangle from coordinate system of Component c to
47 * screen coordinate system.
48 *
49 * @param r a non-null Rectangle
50 * @param c a Component whose coordinate system is used for conversion
51 */
52 public static void convertRectToScreen(Rectangle r, Component c) {
53 Point p = new Point(r.x, r.y);
54 SwingUtilities.convertPointToScreen(p, c);
55 r.x = p.x;
56 r.y = p.y;
57 }
58
59 /**
60 * Compares two bufferedImages pixel-by-pixel.
61 * return true if all pixels in the two areas are identical
62 */
63 public static boolean compareBufferedImages(BufferedImage bufferedImage0, BufferedImage bufferedImage1) {
64 int width = bufferedImage0.getWidth();
65 int height = bufferedImage0.getHeight();
66
67 if (width != bufferedImage1.getWidth() || height != bufferedImage1.getHeight()) {
68 return false;
69 }
70
71 for (int y = 0; y < height; y++) {
72 for (int x = 0; x < width; x++) {
73 if (bufferedImage0.getRGB(x, y) != bufferedImage1.getRGB(x, y)) {
74 return false;
75 }
76 }
77 }
78
79 return true;
80 }
rupashkab1c369f2011-03-14 15:01:53 +030081
82 /**
83 * Fills the heap until OutOfMemoryError occurs. This method is useful for
84 * WeakReferences removing.
85 */
86 public static void generateOOME() {
87 List<Object> bigLeak = new LinkedList<Object>();
88
89 boolean oome = false;
90
91 System.out.print("Filling the heap");
92
93 try {
94 for(int i = 0; true ; i++) {
95 // Now, use up all RAM
96 bigLeak.add(new byte[1024 * 1024]);
97
98 System.out.print(".");
99
100 // Give the GC a change at that weakref
101 if (i % 10 == 0) {
102 System.gc();
103 try {
104 Thread.sleep(100);
105 } catch (InterruptedException e) {
106 e.printStackTrace();
107 }
108 }
109 }
110 } catch (OutOfMemoryError e) {
111 bigLeak = null;
112 oome = true;
113 }
114
115 System.out.println("");
116
117 if (!oome) {
118 throw new RuntimeException("Problem with test case - never got OOME");
119 }
120
121 System.out.println("Got OOME");
122 }
rupashkabef801e2011-10-11 15:22:40 +0400123
124 /**
125 * Find a sub component by class name.
126 * Always run this method on the EDT thread
127 */
128 public static Component findSubComponent(Component parent, String className) {
129 String parentClassName = parent.getClass().getName();
130
131 if (parentClassName.contains(className)) {
132 return parent;
133 }
134
135 if (parent instanceof Container) {
136 for (Component child : ((Container) parent).getComponents()) {
137 Component subComponent = findSubComponent(child, className);
138
139 if (subComponent != null) {
140 return subComponent;
141 }
142 }
143 }
144
145 return null;
146 }
rupashkad37d5142011-11-21 18:22:30 +0400147
148 /**
alexschd7e92532013-03-15 17:02:24 +0400149 * Hits mnemonics by robot.
150 */
151 public static void hitMnemonics(Robot robot, int... keys) {
152
153 ArrayList<Integer> mnemonicKeyCodes = getSystemMnemonicKeyCodes();
154 for (Integer mnemonic : mnemonicKeyCodes) {
155 robot.keyPress(mnemonic);
156 }
157
158 hitKeys(robot, keys);
159
160 for (Integer mnemonic : mnemonicKeyCodes) {
161 robot.keyRelease(mnemonic);
162 }
163 }
164
165 /**
rupashkad37d5142011-11-21 18:22:30 +0400166 * Hits keys by robot.
167 */
168 public static void hitKeys(Robot robot, int... keys) {
169 for (int i = 0; i < keys.length; i++) {
170 robot.keyPress(keys[i]);
171 }
172
173 for (int i = keys.length - 1; i >= 0; i--) {
174 robot.keyRelease(keys[i]);
175 }
176 }
rupashka42a48d92012-04-10 19:09:48 +0300177
178 /**
alexsch5acf8de2012-10-23 14:30:41 +0400179 * Moves mouse smoothly from (x0, y0) to (x1, y1).
180 */
181 public static void glide(Robot robot, int x0, int y0, int x1, int y1) throws AWTException {
182 float dmax = (float) Math.max(Math.abs(x1 - x0), Math.abs(y1 - y0));
183 float dx = (x1 - x0) / dmax;
184 float dy = (y1 - y0) / dmax;
185
186 for (int i = 0; i <= dmax; i += 10) {
187 robot.mouseMove((int) (x0 + dx * i), (int) (y0 + dy * i));
188 }
189 }
190
191 /**
192 * Gets component center point
193 *
194 * @return center point of the <code>component</code>
195 */
196 public static Point getCenterPoint(final Component component) throws Exception {
197 return Util.invokeOnEDT(new Callable<Point>() {
198
199 @Override
200 public Point call() throws Exception {
201 Point p = component.getLocationOnScreen();
202 Dimension size = component.getSize();
203 return new Point(p.x + size.width / 2, p.y + size.height / 2);
204 }
205 });
206 }
207
208 /**
rupashka42a48d92012-04-10 19:09:48 +0300209 * Invokes the <code>task</code> on the EDT thread.
210 *
211 * @return result of the <code>task</code>
212 */
213 public static <T> T invokeOnEDT(final Callable<T> task) throws Exception {
214 final List<T> result = new ArrayList<>(1);
215 final Exception[] exception = new Exception[1];
216
217 SwingUtilities.invokeAndWait(new Runnable() {
218 @Override
219 public void run() {
220 try {
221 result.add(task.call());
222 } catch (Exception e) {
223 exception[0] = e;
224 }
225 }
226 });
227
228 if (exception[0] != null) {
229 throw exception[0];
230 }
231
232 return result.get(0);
233 }
kshefove57475e2013-02-13 19:06:31 +0400234 /**
235 * Gets key codes from system mnemonic key mask
236 * @return key codes list
237 */
238 public static ArrayList<Integer> getSystemMnemonicKeyCodes() {
239 return Util.getKeyCodesFromKeyMask(SwingUtilities2.getSystemMnemonicKeyMask());
240 }
241
242 /**
243 * Gets the key codes list from modifiers
244 * @param modifiers an integer combination of the modifier constants
245 * @return key codes list
246 */
247 public static ArrayList<Integer> getKeyCodesFromKeyMask(int modifiers) {
248 ArrayList<Integer> result = new ArrayList<>();
249 if ((modifiers & InputEvent.CTRL_MASK) != 0) {
250 result.add(KeyEvent.VK_CONTROL);
251 }
252 if ((modifiers & InputEvent.ALT_MASK) != 0) {
253 result.add(KeyEvent.VK_ALT);
254 }
255 if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
256 result.add(KeyEvent.VK_SHIFT);
257 }
258 if ((modifiers & InputEvent.META_MASK) != 0) {
259 result.add(KeyEvent.VK_META);
260 }
261 return result;
262 }
rupashka3bcc9e92011-03-03 17:47:41 +0300263}