diff --git a/test/jdk/java/awt/Focus/QuickTypeTest.java b/test/jdk/java/awt/Focus/QuickTypeTest.java new file mode 100644 index 00000000000..0cfd0ef5f1d --- /dev/null +++ b/test/jdk/java/awt/Focus/QuickTypeTest.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2002, 2023, 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. + */ +/* + @test + @bug 4423838 + @summary KEY_TYPED and KEY_PRESSED generated by the same key are notified to + different TextFields + @key headful + @run main QuickTypeTest +*/ + +import java.awt.AWTException; +import java.awt.BorderLayout; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.EventQueue; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +import java.util.Properties; + +import javax.swing.JFrame; +import javax.swing.JTextField; + +public class QuickTypeTest { + static final int TEST_TIMEOUT=10000; + static JFrame frame1; + static JFrame frame2; + static JTextField tf1; + static JTextField tf2; + static SmartKeyAdapter ska; + static Object keyMonitor; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(() -> { + frame1 = new JFrame("First Frame"); + frame2 = new JFrame("Second Frame"); + tf1 = new JTextField("", 10); + tf2 = new JTextField("", 10); + frame1.getContentPane().add(tf1); + frame2.getContentPane().add(tf2); + frame1.setLocation(200,220); + frame2.setLocation(220,300); + frame1.pack(); + frame2.pack(); + keyMonitor = new Object(); + ska = new SmartKeyAdapter(frame2, keyMonitor); + tf1.addKeyListener(ska); + frame1.setVisible(true); + }); + + Robot robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(100); + robot.waitForIdle(); + robot.delay(1000); + Object tf1Monitor = new Object(); + MonitoredFocusListener monitorer = new MonitoredFocusListener(tf1Monitor); + tf1.addFocusListener(monitorer); + Point origin = tf1.getLocationOnScreen(); + Dimension dim = tf1.getSize(); + robot.mouseMove((int)origin.getX() + (int)dim.getWidth()/2, + (int)origin.getY() + (int)dim.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + + if (!tf1.isFocusOwner()) { + synchronized (tf1Monitor) { + tf1Monitor.wait(TEST_TIMEOUT); + } + } + if (!tf1.isFocusOwner()) { + throw new RuntimeException("TEST FAILED. tf1 doesn't receive focus."); + } + + robot.keyPress(KeyEvent.VK_A); + robot.keyRelease(KeyEvent.VK_A); + robot.keyPress(KeyEvent.VK_B); + robot.keyRelease(KeyEvent.VK_B); + if (!ska.isFrameShown) { + synchronized (keyMonitor) { + keyMonitor.wait(TEST_TIMEOUT); + } + } + if (!ska.isFrameShown) { + throw new RuntimeException("TEST FAILED. Second frame is not shown."); + } + + Object waitMonitor = new Object(); + ReleaseWaiter waiter = new ReleaseWaiter(waitMonitor, KeyEvent.VK_C); + tf1.addKeyListener(waiter); + tf2.addKeyListener(waiter); + robot.keyPress(KeyEvent.VK_C); + robot.keyRelease(KeyEvent.VK_C); + + synchronized (waitMonitor) { + waitMonitor.wait(2000); + } + + if ((tf1.getText().length() > 2) || (tf2.getText().length() < 1)) { + System.out.println("tf1's text = \"" + tf1.getText() + "\""); + System.out.println("tf2's text = \"" + tf2.getText() + "\""); + System.out.println("l1 = " + tf1.getText().length()); + System.out.println("l2 = " + tf2.getText().length()); + throw new RuntimeException("TEST FAILED."); + } + } finally { + EventQueue.invokeAndWait(() -> { + if (frame1 != null) { + frame1.dispose(); + } + if (frame2 != null) { + frame2.dispose(); + } + }); + } + } + + }// class QuickTypeTest + +class ReleaseWaiter extends KeyAdapter { + Object monitor; + int keycode; + public ReleaseWaiter(Object monitor, int keycode) { + this.monitor = monitor; + this.keycode = keycode; + } + + public void keyReleased(KeyEvent ke) { + System.out.println("keyReleased " + ke.getKeyCode()); + if (ke.getKeyCode() == keycode) { + synchronized (monitor) { + monitor.notify(); + } + } + } +} + +class SmartKeyAdapter implements KeyListener { + JFrame frame; + int charCounter = 0; + boolean isFrameShown = false; + Object monitor; + + public SmartKeyAdapter(JFrame frame, Object monitor) { + this.frame = frame; + this.monitor = monitor; + } + + public void keyReleased(KeyEvent ke) { + System.out.println(ke.toString()); + } + public void keyPressed(KeyEvent ke) { + System.out.println(ke.toString()); + charCounter++; + if (charCounter == 2) { + frame.setVisible(true); + isFrameShown = true; + synchronized (monitor) { + monitor.notify(); + } + } + } + public void keyTyped(KeyEvent ke) { + System.out.println(ke.toString()); + } +} + +class MonitoredFocusListener extends FocusAdapter { + Object monitor; + + public MonitoredFocusListener(Object monitor) { + this.monitor = monitor; + } + + public void focusLost(FocusEvent fe) { + System.out.println(fe.toString()); + } + public void focusGained(FocusEvent fe) { + System.out.println(fe.toString()); + synchronized (monitor) { + monitor.notify(); + } + } +} diff --git a/test/jdk/java/awt/Focus/RowToleranceTransitivityTest.java b/test/jdk/java/awt/Focus/RowToleranceTransitivityTest.java new file mode 100644 index 00000000000..099e81a1ab0 --- /dev/null +++ b/test/jdk/java/awt/Focus/RowToleranceTransitivityTest.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2005, 2023, 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. + */ + +/* + @test + @bug 5070991 + @key headful + @summary Tests for a transitivity problem with ROW_TOLERANCE in SortingFTP. + @run main RowToleranceTransitivityTest +*/ +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.KeyboardFocusManager; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import javax.swing.JCheckBox; +import javax.swing.JFrame; +import javax.swing.JFormattedTextField; +import javax.swing.JLabel; +import javax.swing.JPanel; +import java.util.concurrent.atomic.AtomicBoolean; +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.atomic.AtomicBoolean; + +public class RowToleranceTransitivityTest { + static JFrame frame; + static JPanel panel; + static JFormattedTextField ft; + static JCheckBox cb; + static GridBagConstraints gc; + static Robot robot; + + static AtomicBoolean focusGained = new AtomicBoolean(false); + + public static void main(String[] args) throws Exception { + robot = new Robot(); + robot.setAutoDelay(100); + robot.setAutoWaitForIdle(true); + try { + EventQueue.invokeAndWait(() -> { + gc = new GridBagConstraints(); + frame = new JFrame("JFrame"); + JPanel panel = new JPanel(new GridBagLayout()); + ft = new JFormattedTextField(); + cb = new JCheckBox("JCheckBox"); + Dimension dim = new Dimension(100, ft.getPreferredSize().height); + ft.setPreferredSize(dim); + ft.setMinimumSize(dim); + gc.gridx = 5; + gc.gridy = 1; + gc.gridwidth = 10; + panel.add(ft, gc); + + gc.gridy = 3; + panel.add(cb, gc); + + cb.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + System.out.println(e.toString()); + synchronized (focusGained) { + focusGained.set(true); + focusGained.notifyAll(); + } + } + }); + + gc.weightx = 1.0; + gc.gridwidth = 1; + gc.gridy = 0; + gc.gridx = 0; + for (int n = 0; n < 7; n++) { + panel.add(getlabel(), gc); + gc.gridy++; + } + + gc.gridx = 0; + gc.gridy = 0; + for (int n = 0; n < 7; n++) { + panel.add(getlabel(), gc); + gc.gridx++; + } + + frame.getContentPane().add(panel); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + frame.setAlwaysOnTop(true); + + }); + robot.waitForIdle(); + robot.delay(1000); + test(); + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + + static void test() throws Exception { + robot.delay(500); + + // Set focus on the first component to start traversal + if (!setFocusOn(ft, new Runnable() { + public void run() { + clickOn(ft); + } + })) { + System.out.println("Couldn't set focus on " + ft); + throw new RuntimeException("Test couldn't be performed."); + } + + robot.delay(500); + + // Try to traverse + if (!setFocusOn(cb, new Runnable() { + public void run() { + robot.keyPress(KeyEvent.VK_TAB); + } + })) { + System.out.println("Focus got stuck while traversing."); + throw new RuntimeException("Test failed!"); + } + + System.out.println("Test passed."); + } + + static boolean setFocusOn(Component comp, Runnable action) { + + if (KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == comp) { + System.out.println("Already focus owner: " + comp); + return true; + } + + focusGained.set(false); + + System.out.println("Setting focus on " + comp); + + comp.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent e) { + System.out.println(e.toString()); + synchronized (focusGained) { + focusGained.set(true); + focusGained.notifyAll(); + } + } + }); + + action.run(); + + synchronized (focusGained) { + if (!focusGained.get()) { + try { + focusGained.wait(3000); + } catch (InterruptedException e) { + System.out.println("Unexpected exception caught!"); + throw new RuntimeException(e); + } + } + } + + return focusGained.get(); + } + + static JLabel getlabel(){ + Dimension dim = new Dimension(5, 9); // LayoutComparator.ROW_TOLERANCE = 10; + JLabel l = new JLabel("*"); + l.setMinimumSize(dim); + l.setMaximumSize(dim); + l.setPreferredSize(dim); + return l; + } + + static void clickOn(Component c) { + Point p = c.getLocationOnScreen(); + Dimension d = c.getSize(); + + System.out.println("Clicking " + c); + + if (c instanceof Frame) { + robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + ((Frame)c).getInsets().top/2); + } else { + robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + (int)(d.getHeight()/2)); + } + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(); + } + +} diff --git a/test/jdk/java/awt/Focus/TemporaryLostComponentDeadlock.java b/test/jdk/java/awt/Focus/TemporaryLostComponentDeadlock.java new file mode 100644 index 00000000000..e14492ecf16 --- /dev/null +++ b/test/jdk/java/awt/Focus/TemporaryLostComponentDeadlock.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2003, 2023, 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. + */ + +/* + * @test + * @bug 4794413 + * @summary Tests that access to temporaryLostComponent from two different threads doesn't cause a deadlock + * @key headful + * @run main TemporaryLostComponentDeadlock +*/ +import java.awt.Button; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Frame; + +public class TemporaryLostComponentDeadlock { + static Dialog frame1; + static Frame frame; + + public static void main(String[] args) throws Exception { + EventQueue.invokeAndWait(() -> { + frame = new Frame("frame"); + frame1 = new Dialog(frame, "Frame 1", false); + frame1.add(new Button("focus owner")); + frame1.pack(); + frame1.setLocationRelativeTo(null); + frame1.setVisible(true); + }); + + Thread t1 = new Thread() { + public void run() { + synchronized(frame1) { + frame1.dispose(); + synchronized(frame1) { + frame1.notify(); + } + } + } + }; + try { + synchronized(frame1) { + t1.start(); + frame1.wait(); + } + } catch( InterruptedException ie) { + } finally { + if (frame != null) { + frame.dispose(); + } + } + System.out.println("Test PASSED"); + } + +}// class TemporaryLostComponentDeadlock diff --git a/test/jdk/java/awt/Focus/TraversalKeysPropertyNamesTest.java b/test/jdk/java/awt/Focus/TraversalKeysPropertyNamesTest.java new file mode 100644 index 00000000000..aec724e457d --- /dev/null +++ b/test/jdk/java/awt/Focus/TraversalKeysPropertyNamesTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2001, 2023, 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. + */ + +/* + @test + @bug 4457455 + @summary Component and KeyboardFocusManager use wrong names of the properties + @run main TraversalKeysPropertyNamesTest +*/ + +import java.awt.AWTKeyStroke; +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.EventQueue; +import java.awt.KeyboardFocusManager; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.HashSet; + +public class TraversalKeysPropertyNamesTest implements PropertyChangeListener { + final String[] properties = { + "forwardDefaultFocusTraversalKeys", + "backwardDefaultFocusTraversalKeys", + "upCycleDefaultFocusTraversalKeys", + "downCycleDefaultFocusTraversalKeys", + "forwardFocusTraversalKeys", + "backwardFocusTraversalKeys", + "upCycleFocusTraversalKeys", + "downCycleFocusTraversalKeys" + }; + final int PROPERTIES_COUNT = properties.length; + boolean[] flags = new boolean[PROPERTIES_COUNT]; + + public static void main(String[] args) throws Exception { + TraversalKeysPropertyNamesTest test = new TraversalKeysPropertyNamesTest(); + test.start(); + } + + public void start() throws Exception { + EventQueue.invokeAndWait(() -> { + Container cont = new Container() {}; + HashSet forwardKeys = new HashSet(); + forwardKeys.add(AWTKeyStroke.getAWTKeyStroke("ctrl A")); + HashSet backwardKeys = new HashSet(); + backwardKeys.add(AWTKeyStroke.getAWTKeyStroke("ctrl B")); + HashSet upKeys = new HashSet(); + upKeys.add(AWTKeyStroke.getAWTKeyStroke("ctrl C")); + HashSet downKeys = new HashSet(); + downKeys.add(AWTKeyStroke.getAWTKeyStroke("ctrl D")); + + KeyboardFocusManager manager = + KeyboardFocusManager.getCurrentKeyboardFocusManager(); + manager.addPropertyChangeListener(this); + manager.setDefaultFocusTraversalKeys( + KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys); + manager.setDefaultFocusTraversalKeys( + KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys); + manager.setDefaultFocusTraversalKeys( + KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS, downKeys); + manager.setDefaultFocusTraversalKeys( + KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, upKeys); + + cont.addPropertyChangeListener(this); + cont.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, backwardKeys); + cont.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys); + cont.setFocusTraversalKeys(KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS, downKeys); + cont.setFocusTraversalKeys(KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, upKeys); + + for (int i = 0; i < PROPERTIES_COUNT; i++) { + if (!flags[i]) { + throw new RuntimeException( + "Notification on "+properties[i]+" change was not received"); + } + } + }); + }// start() + + public void propertyChange(PropertyChangeEvent pce) { + String property = pce.getPropertyName(); + System.err.println(property); + int index; + for (index = 0; index < PROPERTIES_COUNT; index++) { + if (property.equals(properties[index])) { + break; + } + } + + if (index < PROPERTIES_COUNT) { + flags[index] = true; + } + } + }// class TraversalKeysPropertyNamesTest diff --git a/test/jdk/java/awt/Focus/UpFocusCycleTest.java b/test/jdk/java/awt/Focus/UpFocusCycleTest.java new file mode 100644 index 00000000000..2c421ffe822 --- /dev/null +++ b/test/jdk/java/awt/Focus/UpFocusCycleTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2001, 2023, 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. + */ + +/* + @test + @bug 4394789 + @summary KeyboardFocusManager.upFocusCycle is not working for Swing properly + @key headful + @run main UpFocusCycleTest +*/ +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Color; +import java.awt.DefaultKeyboardFocusManager; +import java.awt.EventQueue; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.Robot; +import javax.swing.DefaultFocusManager; +import javax.swing.JButton; +import javax.swing.JFrame; + +public class UpFocusCycleTest { + static boolean isFailed = true; + static Object sema = new Object(); + static JFrame frame; + + public static void main(String[] args) throws Exception { + try { + Robot robot = new Robot(); + EventQueue.invokeAndWait(() -> { + + frame = new JFrame("Test frame"); + + Container container1 = frame.getContentPane(); + container1.setBackground(Color.yellow); + + JButton button = new JButton("Button"); + button.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + DefaultKeyboardFocusManager manager = new DefaultFocusManager(); + manager.upFocusCycle(button); + System.out.println("Button receive focus"); + frame.addFocusListener(new FocusAdapter() { + public void focusGained(FocusEvent fe) { + System.out.println("Frame receive focus"); + synchronized (sema) { + isFailed = false; + sema.notifyAll(); + } + } + }); + } + }); + container1.add(button,BorderLayout.WEST); + button.requestFocus(); + frame.setSize(300,300); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + if (isFailed) { + System.out.println("Test FAILED"); + throw new RuntimeException("Test FAILED"); + } else { + System.out.println("Test PASSED"); + } + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + }// class UpFocusCycleTest diff --git a/test/jdk/java/awt/Focus/VetoableChangeListenerLoopTest.java b/test/jdk/java/awt/Focus/VetoableChangeListenerLoopTest.java new file mode 100644 index 00000000000..b6449b16dbc --- /dev/null +++ b/test/jdk/java/awt/Focus/VetoableChangeListenerLoopTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2004, 2023, 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. + */ + +/* + @test + @bug 5074189 + @summary Tests that VetoableChangeListener doesn't initiate infinite loop. + @key headful + @run main VetoableChangeListenerLoopTest +*/ +import java.awt.AWTEvent; +import java.awt.Button; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.KeyboardFocusManager; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Robot; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.FocusEvent; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyVetoException; +import java.beans.VetoableChangeListener; + +public class VetoableChangeListenerLoopTest { + static Button b1; + static Button b2; + static Frame frame; + static Robot robot; + + static int counter = 0; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + EventQueue.invokeAndWait(() -> { + KeyboardFocusManager.getCurrentKeyboardFocusManager(). + addVetoableChangeListener(new VetoableChangeListener () { + public void vetoableChange(PropertyChangeEvent evt) + throws PropertyVetoException { + if (b1.equals(evt.getNewValue())) { + System.out.println("VETOING: " + (counter++)); + if (counter > 2) { + throw new RuntimeException("Test failed!"); + } + throw new PropertyVetoException("Change in property", evt); + } + } + }); + + Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { + public void eventDispatched(AWTEvent e) { + System.out.println(e.toString()); + } + }, FocusEvent.FOCUS_EVENT_MASK | WindowEvent.WINDOW_FOCUS_EVENT_MASK); + + b1 = new Button("Button 1"); + b2 = new Button("Button 2"); + Frame frame = new Frame(); + frame.add(b1); + frame.add(b2); + frame.setSize(200, 100); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); + + robot.delay(1000); + test(); + } finally { + if (frame != null) { + frame.dispose(); + } + } + } + + static void test() { + b2.requestFocusInWindow(); + waitTillFocus(b2); + b2.setVisible(false); + } + + + static void waitTillFocus(Component comp) { + while (!checkFocusOwner(comp)) { + robot.delay(100); + } + } + + static boolean checkFocusOwner(Component comp) { + return (comp == KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner()); + } +}