From 7560dbb9258f651a221bc8350816845735929fd9 Mon Sep 17 00:00:00 2001 From: Alexander Zuev Date: Tue, 26 Mar 2024 01:02:20 +0000 Subject: [PATCH] 8316324: Opensource five miscellaneous Swing tests Reviewed-by: prr --- .../javax/swing/InputVerifier/bug4774166.java | 255 ++++++++++++++++++ .../swing/JButton/DefaultButtonLeak.java | 69 +++++ test/jdk/javax/swing/JButton/bug4385611.java | 97 +++++++ .../javax/swing/JComponent/bug4706883.java | 109 ++++++++ .../javax/swing/plaf/motif/bug4150591.java | 42 +++ 5 files changed, 572 insertions(+) create mode 100644 test/jdk/javax/swing/InputVerifier/bug4774166.java create mode 100644 test/jdk/javax/swing/JButton/DefaultButtonLeak.java create mode 100644 test/jdk/javax/swing/JButton/bug4385611.java create mode 100644 test/jdk/javax/swing/JComponent/bug4706883.java create mode 100644 test/jdk/javax/swing/plaf/motif/bug4150591.java diff --git a/test/jdk/javax/swing/InputVerifier/bug4774166.java b/test/jdk/javax/swing/InputVerifier/bug4774166.java new file mode 100644 index 00000000000..644845611b9 --- /dev/null +++ b/test/jdk/javax/swing/InputVerifier/bug4774166.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2004, 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.FlowLayout; +import java.awt.event.KeyEvent; +import java.lang.reflect.InvocationTargetException; +import javax.swing.InputVerifier; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.JWindow; +import javax.swing.SwingUtilities; + +import static java.awt.event.InputEvent.BUTTON1_DOWN_MASK; + +/* + * @test + * @bug 4774166 + * @key headful + * @summary InputVerifier should be called after a window loses and then regains focus + * @library /javax/swing/regtesthelpers + * @build JRobot + * @run main bug4774166 + */ + +class TestPanel extends JPanel { + JTextField tf1 = null; + JTextField tf2 = null; + volatile boolean verifierCalled; + + public void init() { + tf1 = new JTextField(10); + tf2 = new JTextField(10); + + InputVerifier verifier = new InputVerifier() { + public boolean verify(JComponent input) { + verifierCalled = true; + return false; + } + }; + + setLayout(new FlowLayout()); + tf1.setInputVerifier(verifier); + add(tf1); + add(tf2); + validate(); + } +} + +public class bug4774166 { + private static JRobot robot = JRobot.getRobot(); + + JFrame testframe; + JFrame testwindowframe; + JFrame customframe; + JWindow testwindow; + JDialog testdialog; + JTextField frametf1, frametf2, windowtf1, windowtf2, dialogtf1, dialogtf2; + TestPanel testpanel; + + volatile boolean isFocused; + volatile boolean verifierCalled; + + public void setupGUI() { + testframe = new JFrame("Test 4774166"); + testframe.setLayout(new FlowLayout()); + testframe.setBounds(100, 100, 200, 100); + + testwindowframe = new JFrame("Owner of JWindow"); + testwindowframe.setBounds(0, 0, 0, 0); + + testwindow = new JWindow(testwindowframe); + testwindow.setBounds(175, 325, 200, 100); + testwindow.setLayout(new FlowLayout()); + + testdialog = new JDialog((JFrame)null, "Test dialog"); + testdialog.setBounds(420, 100, 200, 100); + testdialog.setLayout(new FlowLayout()); + + InputVerifier verifier = new InputVerifier() { + public boolean verify(JComponent input) { + verifierCalled = true; + return false; + } + }; + + frametf1 = new JTextField(10); + frametf2 = new JTextField(10); + frametf1.setInputVerifier(verifier); + testframe.add(frametf1); + testframe.add(frametf2); + testframe.setVisible(true); + + windowtf1 = new JTextField(10); + windowtf2 = new JTextField(10); + windowtf1.setInputVerifier(verifier); + testwindow.add(windowtf1); + testwindow.add(windowtf2); + testwindowframe.setVisible(true); + testwindow.setVisible(true); + + dialogtf1 = new JTextField(10); + dialogtf2 = new JTextField(10); + dialogtf1.setInputVerifier(verifier); + testdialog.add(dialogtf1); + testdialog.add(dialogtf2); + testdialog.setVisible(true); + + customframe = new JFrame("Frame with custom panel"); + customframe.setLayout(new FlowLayout()); + testpanel = new TestPanel(); + testpanel.init(); + + customframe.add(testpanel); + customframe.setBounds(420, 250, 200, 100); + customframe.pack(); + customframe.setVisible(true); + } + + public void performTest() throws InterruptedException, InvocationTargetException { + robot.setAutoDelay(100); + robot.delay(2000); + + robot.clickMouseOn(frametf1, BUTTON1_DOWN_MASK); + robot.hitKey(KeyEvent.VK_A); + robot.hitKey(KeyEvent.VK_B); + robot.hitKey(KeyEvent.VK_C); + robot.hitKey(KeyEvent.VK_D); + robot.hitKey(KeyEvent.VK_E); + + robot.clickMouseOn(windowtf1, BUTTON1_DOWN_MASK); + robot.hitKey(KeyEvent.VK_F); + robot.hitKey(KeyEvent.VK_G); + robot.hitKey(KeyEvent.VK_H); + robot.hitKey(KeyEvent.VK_I); + robot.hitKey(KeyEvent.VK_J); + + robot.clickMouseOn(dialogtf1, BUTTON1_DOWN_MASK); + robot.hitKey(KeyEvent.VK_K); + robot.hitKey(KeyEvent.VK_L); + robot.hitKey(KeyEvent.VK_M); + robot.hitKey(KeyEvent.VK_N); + robot.hitKey(KeyEvent.VK_O); + + robot.clickMouseOn(testpanel.tf1, BUTTON1_DOWN_MASK); + robot.hitKey(KeyEvent.VK_P); + robot.hitKey(KeyEvent.VK_Q); + robot.hitKey(KeyEvent.VK_R); + robot.hitKey(KeyEvent.VK_S); + robot.hitKey(KeyEvent.VK_T); + + verifierCalled = false; + robot.clickMouseOn(frametf2, BUTTON1_DOWN_MASK); + robot.delay(2000); + SwingUtilities.invokeAndWait(() -> { + isFocused = frametf1.isFocusOwner(); + }); + if (!isFocused) { + throw new RuntimeException("Focus error. Test failed!"); + } + if (!verifierCalled) { + throw new RuntimeException("Verifier was not called upon regaining focus"); + } + + verifierCalled = false; + robot.clickMouseOn(windowtf2, BUTTON1_DOWN_MASK); + robot.delay(2000); + SwingUtilities.invokeAndWait(() -> { + isFocused = windowtf1.isFocusOwner(); + }); + if (!isFocused) { + throw new RuntimeException("Focus error. Test failed!"); + } + if (!verifierCalled) { + throw new RuntimeException("Verifier was not called upon regaining focus"); + } + + testpanel.verifierCalled = false; + robot.clickMouseOn(testpanel.tf2, BUTTON1_DOWN_MASK); + robot.delay(2000); + SwingUtilities.invokeAndWait(() -> { + isFocused = testpanel.tf1.isFocusOwner(); + }); + if (!isFocused) { + throw new RuntimeException("Focus error. Test failed!"); + } + if (!testpanel.verifierCalled) { + throw new RuntimeException("Verifier was not called upon regaining focus"); + } + + verifierCalled = false; + robot.clickMouseOn(dialogtf2, BUTTON1_DOWN_MASK); + robot.delay(2000); + SwingUtilities.invokeAndWait(() -> { + isFocused = dialogtf1.isFocusOwner(); + }); + if (!isFocused) { + throw new RuntimeException("Focus error. Test failed!"); + } + if (!verifierCalled) { + throw new RuntimeException("Verifier was not called upon regaining focus"); + } + } + + public void cleanupGUI() { + if (testframe != null) { + testframe.dispose(); + } + if (testwindowframe != null) { + testwindowframe.dispose(); + } + if (testwindow != null) { + testwindow.dispose(); + } + if (customframe != null) { + customframe.dispose(); + } + if (testdialog != null) { + testdialog.dispose(); + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + bug4774166 b = new bug4774166(); + SwingUtilities.invokeAndWait(b::setupGUI); + try { + b.performTest(); + } finally { + SwingUtilities.invokeAndWait(b::cleanupGUI); + } + } +} diff --git a/test/jdk/javax/swing/JButton/DefaultButtonLeak.java b/test/jdk/javax/swing/JButton/DefaultButtonLeak.java new file mode 100644 index 00000000000..5e03902e64b --- /dev/null +++ b/test/jdk/javax/swing/JButton/DefaultButtonLeak.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 1999, 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.BorderLayout; +import java.awt.GridLayout; +import java.lang.reflect.InvocationTargetException; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + +/* + * @test + * @bug 4134035 + * @key headful + * @summary Ensure default button reference is removed from the RootPane + * when a hierarchy containing the RootPane's default button is removed + * from the RootPane. (a memory leak) + * @run main DefaultButtonLeak + */ + +public class DefaultButtonLeak { + public static void main(String[] args) throws InterruptedException, InvocationTargetException { + SwingUtilities.invokeAndWait(() -> { + JFrame frame = new JFrame("DefaultButtonLeak"); + try { + JPanel bigPanel = new JPanel(); + bigPanel.setLayout(new GridLayout(10, 10)); + for (int i = 0; i < 100; i++) { + JButton button = new JButton("Button" + i); + bigPanel.add(button); + if (i == 0) { + frame.getRootPane().setDefaultButton(button); + } + } + frame.add(bigPanel, BorderLayout.CENTER); + frame.pack(); + frame.setVisible(true); + frame.remove(bigPanel); + if (frame.getRootPane().getDefaultButton() != null) { + throw new RuntimeException("RootPane default button reference not removed."); + } + } finally { + frame.setVisible(false); + frame.dispose(); + } + }); + } +} diff --git a/test/jdk/javax/swing/JButton/bug4385611.java b/test/jdk/javax/swing/JButton/bug4385611.java new file mode 100644 index 00000000000..b7360f27360 --- /dev/null +++ b/test/jdk/javax/swing/JButton/bug4385611.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2001, 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.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.image.BufferedImage; +import java.lang.reflect.InvocationTargetException; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +/* + * @test + * @bug 4385611 8078655 + * @requires (os.family == "windows") + * @summary The button's preferred width/height calculation. + * @run main bug4385611 + */ + +public class bug4385611 { + static JButton bt1, bt2; + static final ImageIcon icon32x32 = generateImageIcon(); + static final Dimension DIM_32X32 = new Dimension(32, 32); + static final Dimension DIM_33X33 = new Dimension(33, 33); + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + SwingUtilities.invokeAndWait(() -> { + try { + UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); + bt1 = new JButton(icon32x32); + bt1.setMargin(new Insets(0, 0, 0, 0)); + bt1.setBorder(null); + bt1.setFocusPainted(true); + + bt2 = new JButton(icon32x32); + bt2.setMargin(new Insets(0, 0, 0, 0)); + bt2.setBorder(null); + bt2.setFocusPainted(false); + + if (!bt1.getPreferredSize().equals(DIM_32X32) || + !bt2.getPreferredSize().equals(DIM_32X32)) { + throw new RuntimeException("The button's preferred size should be 32x32"); + } + } catch (Exception e) { + throw new RuntimeException("Can not initialize Metal LnF", e); + } + + try { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + bt1.updateUI(); + bt1.setBorder(null); + bt2.updateUI(); + bt2.setBorder(null); + if (!bt1.getPreferredSize().equals(DIM_33X33) || + !bt2.getPreferredSize().equals(DIM_32X32)) { + throw new RuntimeException("The button's preferred size should be " + + "33x33 and 32x32 correspondingly."); + } + } catch (Exception e) { + throw new RuntimeException("Can not initialize Windows LnF", e); + } + }); + } + + private static ImageIcon generateImageIcon() { + BufferedImage image = new BufferedImage(32, 32, BufferedImage.TYPE_INT_ARGB); + Graphics g = image.createGraphics(); + g.setColor(Color.YELLOW); + g.fillRect(0, 0, 32, 32); + g.dispose(); + return new ImageIcon(image); + } +} diff --git a/test/jdk/javax/swing/JComponent/bug4706883.java b/test/jdk/javax/swing/JComponent/bug4706883.java new file mode 100644 index 00000000000..7375342c7a4 --- /dev/null +++ b/test/jdk/javax/swing/JComponent/bug4706883.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2003, 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.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.Date; +import javax.swing.AbstractAction; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; + +/* + * @test + * @bug 4706883 + * @summary REGRESSION: ActionMap misses VK_PRINTSCREEN + * @key headful + * @run main bug4706883 + */ + +public class bug4706883 { + + MyPanel panel; + JFrame fr; + boolean passed = false; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + bug4706883 test = new bug4706883(); + SwingUtilities.invokeAndWait(test::init); + SwingUtilities.invokeAndWait(test::test); + } + public void init() { + fr = new JFrame("Test"); + + panel = new MyPanel(); + fr.add(panel); + + panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put + (KeyStroke.getKeyStroke(KeyEvent.VK_PRINTSCREEN, 0, true), + "RELEASED"); + + panel.getActionMap().put("RELEASED", new AbstractAction() { + public void actionPerformed(ActionEvent ev) { + setPassed(true); + } + }); + + fr.setSize(200, 200); + fr.setVisible(true); + } + + public void test() { + panel.doTest(); + try { + Thread.sleep(1000); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (fr != null) { + fr.setVisible(false); + fr.dispose(); + } + } + if (!isPassed()) { + throw new RuntimeException("The key binding for VK_PRINTSCREEN wasn't processed"); + } + } + + class MyPanel extends JPanel { + public void doTest() { + KeyEvent e = new KeyEvent(this, KeyEvent.KEY_RELEASED, + (new Date()).getTime(), + 0, KeyEvent.VK_PRINTSCREEN, + KeyEvent.CHAR_UNDEFINED); + processKeyEvent(e); + } + } + + synchronized void setPassed(boolean passed) { + this.passed = passed; + } + + synchronized boolean isPassed() { + return passed; + } +} diff --git a/test/jdk/javax/swing/plaf/motif/bug4150591.java b/test/jdk/javax/swing/plaf/motif/bug4150591.java new file mode 100644 index 00000000000..66c668a441c --- /dev/null +++ b/test/jdk/javax/swing/plaf/motif/bug4150591.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 1999, 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 com.sun.java.swing.plaf.motif.MotifInternalFrameTitlePane; +import javax.swing.JInternalFrame; + +/* + * @test + * @bug 4150591 + * @summary MotifInternalFrameTitlePane is public now and can be + * instantiated by other classes within the desktop module without using Reflection. + * This does not mean that this class will ever become part + * of the official public Java API. + * @modules java.desktop/com.sun.java.swing.plaf.motif + * @run main bug4150591 + */ + +public class bug4150591 { + public static void main(String[] args) { + MotifInternalFrameTitlePane mtp = new MotifInternalFrameTitlePane(new JInternalFrame()); + } +}