/* * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import java.awt.Button; import java.awt.Checkbox; import java.awt.Choice; import java.awt.Component; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.Label; import java.awt.List; import java.awt.Panel; import java.awt.Point; import java.awt.Robot; import java.awt.Scrollbar; import java.awt.TextArea; import java.awt.TextField; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.InputEvent; import java.lang.reflect.InvocationTargetException; import jdk.test.lib.Platform; /* * @test * @key headful * @bug 8333403 * @summary Test performs various operations to check components events are triggered properly. * @library /test/lib * @build jdk.test.lib.Platform * @run main ComponentEventTest */ public class ComponentEventTest { private static final int DELAY = 500; private static Frame frame; private static Robot robot; private static Component[] components; private static volatile Point centerPoint; private static volatile boolean componentHidden; private static volatile boolean componentShown; private static volatile boolean componentMoved; private static volatile boolean componentResized; private static final ComponentListener componentListener = new ComponentListener() { @Override public void componentShown(ComponentEvent e) { System.out.println("ComponentShown: " + e.getSource()); componentShown = true; } @Override public void componentResized(ComponentEvent e) { System.out.println("ComponentResized: " + e.getSource()); componentResized = true; } @Override public void componentMoved(ComponentEvent e) { System.out.println("ComponentMoved: " + e.getSource()); componentMoved = true; } @Override public void componentHidden(ComponentEvent e) { System.out.println("ComponentHidden: " + e.getSource()); componentHidden = true; } }; private static void initializeGUI() { frame = new Frame("Component Event Test"); frame.setLayout(new FlowLayout()); Panel panel = new Panel(); Button button = new Button("Button"); Label label = new Label("Label"); List list = new List(); list.add("One"); list.add("Two"); list.add("Three"); Choice choice = new Choice(); choice.add("Red"); choice.add("Orange"); choice.add("Yellow"); Checkbox checkbox = new Checkbox("Checkbox"); Scrollbar scrollbar = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 255); TextField textfield = new TextField(15); TextArea textarea = new TextArea(5, 15); components = new Component[] { panel, button, label, list, choice, checkbox, scrollbar, textfield, textarea, frame }; for (int i = 0; i < components.length - 1; i++) { components[i].addComponentListener(componentListener); frame.add(components[i]); } frame.addComponentListener(componentListener); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) throws Exception { try { robot = new Robot(); robot.setAutoWaitForIdle(true); EventQueue.invokeAndWait(ComponentEventTest::initializeGUI); robot.waitForIdle(); robot.delay(DELAY); doTest(); System.out.println("Test PASSED"); } finally { EventQueue.invokeAndWait(ComponentEventTest::disposeFrame); } } private static void doTest() throws InvocationTargetException, InterruptedException { // Click the frame to ensure it gains focus clickFrame(); robot.delay(DELAY); for (int i = 0; i < components.length; i++) { for (boolean state : new boolean[] { true, false }) { doTest(components[i], state); } } robot.delay(DELAY); System.out.println("Iconify frame"); resetValues(); testIconifyFrame(); System.out.println("Deiconify frame"); resetValues(); testDeiconifyFrame(); } private static void clickFrame() throws InvocationTargetException, InterruptedException { EventQueue.invokeAndWait(() -> { Point location = frame.getLocationOnScreen(); Dimension size = frame.getSize(); centerPoint = new Point(location.x + size.width / 2, location.y + size.height / 2); }); robot.mouseMove(centerPoint.x, centerPoint.y); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); } private static void testIconifyFrame() throws InvocationTargetException, InterruptedException { EventQueue.invokeAndWait(() -> frame.setExtendedState(Frame.ICONIFIED)); robot.waitForIdle(); robot.delay(DELAY); if (componentShown || componentHidden || componentMoved || componentResized) { throw new RuntimeException( "ComponentEvent triggered when frame is iconified"); } } private static void testDeiconifyFrame() throws InvocationTargetException, InterruptedException { EventQueue.invokeAndWait(() -> frame.setExtendedState(Frame.NORMAL)); robot.waitForIdle(); robot.delay(DELAY); /* * Because of the different behavior between MS Windows and other OS, we * receive native events WM_SIZE and WM_MOVE on Windows when the frame * state changes from iconified to normal. AWT sends these events to * components when it receives the events from the native system. See * JDK-6754618 for more information. */ if (componentShown || componentHidden) { throw new RuntimeException( "FAIL: componentShown or componentHidden triggered " + "when frame set to normal"); } if (Platform.isWindows() && (!componentMoved || !componentResized)) { throw new RuntimeException( "FAIL: componentMoved or componentResized wasn't triggered " + "when frame set to normal"); } if (!Platform.isWindows() && (componentMoved || componentResized)) { throw new RuntimeException( "FAIL: componentMoved or componentResized triggered " + "when frame set to normal"); } } private static void doTest(final Component currentComponent, boolean enable) throws InvocationTargetException, InterruptedException { System.out.println("Component " + currentComponent); System.out.println(" enabled " + enable); EventQueue.invokeAndWait(() -> { currentComponent.setEnabled(enable); revalidateFrame(); }); robot.delay(DELAY); resetValues(); EventQueue.invokeAndWait(() -> { currentComponent.setVisible(false); revalidateFrame(); }); robot.delay(DELAY); if (!componentHidden) { throw new RuntimeException("FAIL: ComponentHidden not triggered for" + currentComponent.getClass()); } resetValues(); EventQueue.invokeAndWait(() -> { currentComponent.setVisible(false); revalidateFrame(); }); robot.delay(DELAY); if (componentHidden) { throw new RuntimeException("FAIL: ComponentHidden triggered when " + "setVisible(false) called for a hidden " + currentComponent.getClass()); } resetValues(); EventQueue.invokeAndWait(() -> { currentComponent.setVisible(true); revalidateFrame(); }); robot.delay(DELAY); if (!componentShown) { throw new RuntimeException("FAIL: ComponentShown not triggered for " + currentComponent.getClass()); } resetValues(); EventQueue.invokeAndWait(() -> { currentComponent.setVisible(true); revalidateFrame(); }); robot.delay(DELAY); if (componentShown) { throw new RuntimeException("FAIL: ComponentShown triggered when " + "setVisible(true) called for a shown " + currentComponent.getClass()); } resetValues(); EventQueue.invokeAndWait(() -> { currentComponent.setLocation(currentComponent.getLocation().x + 1, currentComponent.getLocation().y); revalidateFrame(); }); robot.delay(DELAY); if (!componentMoved) { throw new RuntimeException("FAIL: ComponentMoved not triggered for " + currentComponent.getClass()); } resetValues(); EventQueue.invokeAndWait(() -> { currentComponent.setSize(currentComponent.getSize().width + 1, currentComponent.getSize().height); revalidateFrame(); }); robot.delay(DELAY); if (!componentResized) { throw new RuntimeException("FAIL: ComponentResized not triggered " + "when size increases for " + currentComponent.getClass()); } resetValues(); EventQueue.invokeAndWait(() -> { currentComponent.setSize(currentComponent.getSize().width - 1, currentComponent.getSize().height); revalidateFrame(); }); robot.delay(DELAY); if (!componentResized) { throw new RuntimeException("FAIL: ComponentResized not triggered " + "when size decreases for " + currentComponent.getClass()); } System.out.println("\n"); } private static void revalidateFrame() { frame.invalidate(); frame.validate(); } private static void resetValues() { componentShown = false; componentHidden = false; componentMoved = false; componentResized = false; } private static void disposeFrame() { if (frame != null) { frame.dispose(); } } }