diff --git a/test/jdk/java/awt/Dialog/DialogDeadlockTest.java b/test/jdk/java/awt/Dialog/DialogDeadlockTest.java new file mode 100644 index 00000000000..87a929053c7 --- /dev/null +++ b/test/jdk/java/awt/Dialog/DialogDeadlockTest.java @@ -0,0 +1,129 @@ +/* + * 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 5006427 + @summary Shows many modal dialog and checks if there is a deadlock or thread race. + @key headful + @run main DialogDeadlockTest +*/ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Window; +import java.lang.reflect.InvocationTargetException; +import java.util.LinkedList; +import java.util.List; + +public class DialogDeadlockTest { + public static final int MAX_COUNT = 200; + private static Dialog lastDialog; + private static Runnable r; + private static volatile int count; + private static volatile int cumul; + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + DialogDeadlockTest ddt = new DialogDeadlockTest(); + ddt.start(); + } + + public void start() { + final Frame frame = new Frame("abc"); + final List toDispose = new LinkedList<>(); + + try { + frame.setLocation(300, 0); + frame.add(new Button("def")); + frame.pack(); + frame.setVisible(true); + cumul = 0; + + r = new Runnable() { + public void run() { + count++; + if (count < 10) { + Dialog xlastDialog = lastDialog; + cumul += count; + Dialog d = new Dialog(frame, "Dialog " + + cumul, true); + d.setLayout(new BorderLayout()); + d.add(new Button("button " + count), BorderLayout.CENTER); + d.pack(); + toDispose.add(d); + lastDialog = d; + EventQueue.invokeLater(r); + d.setVisible(true); + if (xlastDialog != null) { + xlastDialog.setVisible(false); + } else { + if (cumul < MAX_COUNT) { + count = 0; + lastDialog = null; + EventQueue.invokeLater(r); + } + } + } else { + try { + Thread.sleep(1000); + } catch (InterruptedException ignore) { + } + lastDialog.setVisible(false); + lastDialog = null; + } + } + }; + try { + EventQueue.invokeAndWait(r); + } catch (InterruptedException ignore) { + } catch (Exception e) { + throw new RuntimeException("Unexpected exception: " + + e.getLocalizedMessage()); + } + while (cumul < MAX_COUNT - 1) { + try { + Thread.sleep(1000); + } catch (InterruptedException ignore) {} + } + System.out.println("Test PASSED"); + } finally { + try { + EventQueue.invokeAndWait(() -> { + frame.setVisible(false); + frame.dispose(); + for (Window w: toDispose) { + w.dispose(); + } + }); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } +} diff --git a/test/jdk/java/awt/Dialog/DialogLocationTest.java b/test/jdk/java/awt/Dialog/DialogLocationTest.java new file mode 100644 index 00000000000..b5f21780a40 --- /dev/null +++ b/test/jdk/java/awt/Dialog/DialogLocationTest.java @@ -0,0 +1,182 @@ +/* + * Copyright (c) 1999, 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 4101437 + @summary Dialog.setLocation(int,int) works unstable when the dialog is visible + @key headful + @run main DialogLocationTest +*/ + +import java.awt.AWTException; +import java.awt.Container; +import java.awt.Dialog; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.GraphicsEnvironment; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.lang.reflect.InvocationTargetException; +import java.util.Random; + +public class DialogLocationTest extends Panel { + private volatile int count = 0; + private Dialog my_dialog; + private volatile boolean waitingForEvent = false; + private volatile int newX, newY; + Random random = new Random(); + + public void init() { + Container f = getParent(); + + while (!(f instanceof Frame)) { + f = f.getParent(); + } + + my_dialog = new Dialog((Frame) f, "TestDialog"); + my_dialog.setSize(150, 100); + + setSize(200, 200); + } + + public void start() throws InterruptedException, + InvocationTargetException { + Robot robot; + try { + robot = new Robot(); + EventQueue.invokeAndWait(() -> { + my_dialog.setLocationRelativeTo(null); + my_dialog.setVisible(true); + }); + robot.waitForIdle(); + robot.delay(1000); + my_dialog.addComponentListener(new CL()); + setDialogLocation(my_dialog); + } catch (AWTException e) { + throw new RuntimeException(e); + } finally { + EventQueue.invokeAndWait(() -> { + my_dialog.setVisible(false); + my_dialog.dispose(); + }); + } + } + + public void setDialogLocation(Dialog dialog) { + int height, width, insetX, insetY; + Point curLoc; + int i; + + Rectangle screen = GraphicsEnvironment + .getLocalGraphicsEnvironment() + .getMaximumWindowBounds(); + height = screen.height; + width = screen.width; + insetX = screen.x; + insetY = screen.y; + + String message = "Failed on iteration %d expect:[%d,%d] " + + "reported:[%d,%d] diff:[%d,%d]"; + + for (i = 0; i < 100; i++) { + newX = random.nextInt(insetX, width - 300); + newY = random.nextInt(insetY, height - 400); + + if (newX == 0 && newY == 0) { + i--; + continue; + } + + waitingForEvent = true; + + EventQueue.invokeLater(() -> { + dialog.setLocation(newX, newY); + }); + + while (waitingForEvent) { + Thread.yield(); + } + + curLoc = dialog.getLocation(); + if (curLoc.x != newX || curLoc.y != newY) { + count++; + System.out.println(message.formatted(i, newX, newY, + curLoc.x, curLoc.y, curLoc.x - newX, curLoc.y - newY)); + System.out.flush(); + } + } + + if (count > 0) { + throw new RuntimeException("Dialog Location was set incorrectly"); + } + } + + public class CL extends ComponentAdapter { + int lastX, lastY; + String message = "Failed in componentMoved() expect:[%d,%d]" + + " reported: [%d,%d] diff [%d,%d]"; + + public void componentMoved(ComponentEvent e) { + if (e.getComponent() == my_dialog) { + Point eventLoc = e.getComponent().getLocation(); + if (lastX != eventLoc.x || lastY != eventLoc.y) { + lastX = eventLoc.x; + lastY = eventLoc.y; + if (newX != 0 && newY != 0 && (eventLoc.x != newX || eventLoc.y != newY)) { + count++; + System.out.println(message.formatted(newX, newY, + eventLoc.x, eventLoc.y, + eventLoc.x - newX, eventLoc.y - newY)); + System.out.flush(); + } + waitingForEvent = false; + } + } + } + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + Frame frame = new Frame("DialogLocationTest"); + try { + DialogLocationTest test = new DialogLocationTest(); + EventQueue.invokeAndWait(() -> { + frame.add(test); + test.init(); + frame.setVisible(true); + }); + test.start(); + } finally { + EventQueue.invokeLater(() -> { + frame.setVisible(false); + frame.dispose(); + }); + } + } +} + diff --git a/test/jdk/java/awt/Dialog/ModalDialogOnNonEdt.java b/test/jdk/java/awt/Dialog/ModalDialogOnNonEdt.java new file mode 100644 index 00000000000..a7a9565d054 --- /dev/null +++ b/test/jdk/java/awt/Dialog/ModalDialogOnNonEdt.java @@ -0,0 +1,136 @@ +/* + * 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 4636311 4645035 + @summary Modal dialog shown on EDT after modal dialog on EDT doesn't receive mouse events + @key headful + @run main ModalDialogOnNonEdt +*/ + +import java.awt.Dialog; +import java.awt.Frame; +import java.awt.EventQueue; +import java.awt.Robot; +import java.awt.Point; +import java.awt.Dimension; +import java.awt.Window; +import java.awt.event.InputEvent; +import java.awt.AWTException; +import java.awt.event.MouseEvent; +import java.awt.event.MouseAdapter; +import java.util.ArrayList; +import java.util.List; + +public class ModalDialogOnNonEdt { + + public void start () { + ShowModalDialog showModalDialog = new ShowModalDialog(); + + try { + EventQueue.invokeLater(showModalDialog); + Robot robot = new Robot(); + robot.delay(2000); + + Point origin = ShowModalDialog.lastShownDialog.getLocationOnScreen(); + Dimension dim = ShowModalDialog.lastShownDialog.getSize(); + robot.mouseMove((int)origin.getX() + (int)dim.getWidth()/2, + (int)origin.getY() + (int)dim.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + robot.delay(2000); + if (ShowModalDialog.count < 2) { + throw new RuntimeException("TEST FAILED: second modal dialog was not shown"); + } + + /* click on second modal dialog to verify if it receives mouse events */ + synchronized (ShowModalDialog.monitor) { + origin = ShowModalDialog.lastShownDialog.getLocationOnScreen(); + dim = ShowModalDialog.lastShownDialog.getSize(); + robot.mouseMove((int)origin.getX() + (int)dim.getWidth()/2, + (int)origin.getY() + (int)dim.getHeight()/2); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + + ShowModalDialog.monitor.wait(2000); + } + + if (ShowModalDialog.count < 3) { + throw new RuntimeException("TEST FAILED: second modal dialog didn't receive mouse events"); + } + + } catch (AWTException e) { + e.printStackTrace(); + throw new RuntimeException("Some AWTException occurred"); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException("Test was interrupted"); + } finally { + for (Window w : ShowModalDialog.toDispose) { + w.setVisible(false); + w.dispose(); + } + } + + System.out.println("TEST PASSED"); + } + + public static void main(String[] args) { + new ModalDialogOnNonEdt().start(); + } +} + +class ShowModalDialog implements Runnable { + static volatile int count = 0; + static Object monitor = new Object(); + static Dialog lastShownDialog; + static List toDispose = new ArrayList<>(); + + public void run() { + count++; + Frame frame = new Frame("Frame #" + count); + toDispose.add(frame); + Dialog dialog = new Dialog(frame, "Modal Dialog #" + count, true); + dialog.setSize(100, 100); + dialog.setLocation(100, 100*count); + dialog.addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent me) { + System.out.println(me.toString()); + if (ShowModalDialog.count < 2) { + Runnable runner = new ShowModalDialog(); + new Thread(runner).start(); + } else { + synchronized (monitor) { + ShowModalDialog.count++; + monitor.notifyAll(); + } + } + } + }); + lastShownDialog = dialog; + toDispose.add(dialog); + dialog.setVisible(true); + } +} diff --git a/test/jdk/java/awt/Dialog/NewMessagePumpTest.java b/test/jdk/java/awt/Dialog/NewMessagePumpTest.java new file mode 100644 index 00000000000..084d0f2e43c --- /dev/null +++ b/test/jdk/java/awt/Dialog/NewMessagePumpTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 1998, 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 4119383 + @summary Tests total rewrite of modality blocking model + @key headful + @run main/timeout=30 NewMessagePumpTest +*/ + +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.lang.reflect.InvocationTargetException; + +public class NewMessagePumpTest { + public void start() { + Frame1 frame = new Frame1(); + frame.validate(); + frame.setVisible(true); + } + + public static void main(String[] args) throws InterruptedException, + InvocationTargetException { + NewMessagePumpTest test = new NewMessagePumpTest(); + EventQueue.invokeAndWait(test::start); + } +} + +class Frame1 extends Frame { + Frame1() { + try { + jbInit(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void jbInit() throws Exception { + MyPanel panel1 = new MyPanel(this); + this.setLayout(new BorderLayout()); + this.setSize(new Dimension(400, 300)); + this.setLocationRelativeTo(null); + this.setTitle("Frame Title"); + panel1.setLayout(new BorderLayout()); + this.add(panel1, BorderLayout.CENTER); + } +} + +class Dialog1 extends Dialog { + BorderLayout borderLayout1 = new BorderLayout(); + Button button1 = new Button(); + + Dialog1(Frame f) { + super(f, true); + try { + jbInit(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + void jbInit() throws Exception { + button1.setLabel("close"); + button1.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + button1_actionPerformed(e); + } + }); + this.setLayout(borderLayout1); + this.add(button1, BorderLayout.NORTH); + } + + void button1_actionPerformed(ActionEvent e) { + dispose(); + } +} + +class MyPanel extends Panel { + Frame frame; + + MyPanel(Frame f) { + frame = f; + } + + public void addNotify() { + super.addNotify(); + System.out.println("AddNotify bringing up modal dialog..."); + final Dialog1 dlg = new Dialog1(frame); + dlg.pack(); + new Thread(() -> { + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + try { + EventQueue.invokeAndWait(() -> { + dlg.setVisible(false); + dlg.dispose(); + }); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + }).start(); + dlg.setVisible(true); + frame.setVisible(false); + frame.dispose(); + System.out.println("Test passed"); + } +}