1 /*
2  * Copyright (c) 2006, 2016, 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 java.awt.*;
25 import java.awt.event.InputEvent;
26 
27 /*
28  * @test
29  * @key headful
30  * @summary Have different components having different preferred sizes
31  *          added to a grid layout having various values of row/columns.
32  *          Check if the compnents are correctly laid out.
33  *          The strategy followed is to calculate the component location
34  *          depending on the preferred sizes and gaps and click the cornors
35  *          of the components to check if events are triggered
36  * @library ../../../../lib/testlibrary/
37  * @run main ComponentPreferredSize
38  * @run main ComponentPreferredSize -hg 20 -vg 20
39  */
40 
41 public class ComponentPreferredSize {
42 
43     private int width = 300;
44     private int height = 200;
45     private final int hGap, vGap;
46     private final int rows = 3;
47     private final int columns = 2;
48     private final int componentCount = 6;
49 
50     private Button[] buttons;
51     private Frame frame;
52 
53     private Robot robot;
54     private GridLayout layout;
55 
56     private volatile boolean actionPerformed = false;
57 
ComponentPreferredSize(int hGap, int vGap)58     public ComponentPreferredSize(int hGap, int vGap) throws Exception {
59         this.hGap = hGap;
60         this.vGap = vGap;
61         robot = new Robot();
62         EventQueue.invokeAndWait( () -> {
63             frame = new Frame("Test frame");
64             frame.setSize(width, height);
65             layout = new GridLayout(rows, columns, hGap, vGap);
66             frame.setLayout(layout);
67 
68             buttons = new Button[componentCount];
69             for (int i = 0; i < componentCount; i++) {
70                 buttons[i] = new Button("Button" + i);
71                 buttons[i].setPreferredSize(new Dimension((int) Math.random() * 100,
72                         (int) Math.random() * 100));
73                 frame.add(buttons[i]);
74                 buttons[i].addActionListener((event) -> {actionPerformed = true;});
75             }
76 
77             frame.setVisible(true);
78         });
79     }
80 
main(String[] args)81     public static void main(String[] args) throws Exception {
82         int hGap = 0;
83         int vGap = 0;
84         for (int i = 0; i < args.length; i++) {
85             switch (args[i]) {
86                 case "-hg":
87                     hGap = Integer.parseInt(args[++i]);
88                     break;
89                 case "-vg":
90                     vGap = Integer.parseInt(args[++i]);
91                     break;
92             }
93         }
94         new ComponentPreferredSize(hGap, vGap).doTest();
95     }
96 
resizeFrame()97     private void resizeFrame() throws Exception {
98         EventQueue.invokeAndWait(() -> {
99             Insets insets = frame.getInsets();
100             double dH = (height-insets.top-insets.bottom - vGap*(rows-1)) % rows;
101             double dW = (width-insets.left-insets.right - hGap*(columns-1)) % columns;
102             height -= dH;
103             width -= dW;
104             frame.setSize(width, height);
105             frame.revalidate();
106         });
107         robot.waitForIdle();
108     }
109 
testBoundaries(int topLeftX, int topLeftY, int bottomRightX, int bottomRightY)110     public void testBoundaries(int topLeftX, int topLeftY, int bottomRightX, int bottomRightY) throws Exception {
111 
112         actionPerformed = false;
113         robot.mouseMove(topLeftX, topLeftY);
114         robot.delay(500);
115         robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
116         robot.delay(500);
117         robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
118         robot.delay(3000);
119 
120         if (!actionPerformed) {
121             frame.dispose();
122             throw new RuntimeException("Clicking on the left top of button did not trigger action event");
123         }
124 
125         actionPerformed = false;
126         robot.mouseMove(bottomRightX, bottomRightY);
127         robot.delay(500);
128         robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
129         robot.delay(500);
130         robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
131         robot.delay(3000);
132 
133         if (!actionPerformed) {
134             frame.dispose();
135             throw new RuntimeException("Clicking on the bottom right of button did not trigger action event");
136         }
137     }
138 
doTest()139     private void doTest() throws Exception {
140         robot.waitForIdle();
141         resizeFrame();
142 
143         int availableWidth = width - frame.getInsets().left -
144                 frame.getInsets().right;
145         int componentWidth = (availableWidth + hGap) / columns - hGap;
146         int availableHeight = height - frame.getInsets().top -
147                 frame.getInsets().bottom;
148         int componentHeight = (availableHeight + vGap) / rows - vGap;
149 
150         for (int i = 0; i < buttons.length; i++) {
151             if (buttons[i].getSize().width != componentWidth ||
152                     buttons[i].getSize().height != componentHeight) {
153                 frame.dispose();
154                 throw new RuntimeException(
155                         "FAIL: Button " + i + " not of proper size" +
156                         "Expected: " + componentWidth + "*" + componentHeight +
157                         "Actual: " + buttons[i].getSize().width + "*" + buttons[i].getSize().height);
158             }
159         }
160 
161         // Components are visible. They should trigger events.
162         // Now you can check for the actual size shown.
163         int currentRow = 1;
164         int currentColumn = 0;
165         for (int i = 0; i < buttons.length; i++) {
166             currentColumn++;
167             if (currentColumn > columns) {
168                 currentColumn = 1;
169                 currentRow++;
170             }
171 
172             int topPosX = frame.getLocationOnScreen().x +
173                     frame.getInsets().left +
174                     (currentColumn - 1) * (componentWidth + hGap);
175             int topPosY = frame.getLocationOnScreen().y +
176                     frame.getInsets().top +
177                     (currentRow - 1) * (componentHeight + vGap);
178 
179             int bottomPosX = topPosX + componentWidth - 1;
180             int bottomPosY = topPosY + componentHeight - 1;
181             testBoundaries(topPosX, topPosY, bottomPosX, bottomPosY);
182         }
183 
184         frame.dispose();
185     }
186 }
187