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
24import java.awt.*;
25import 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
41public 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
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
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
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
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
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