1 import javax.imageio.ImageIO; 2 import javax.swing.JDialog; 3 import javax.swing.JFrame; 4 import javax.swing.SwingUtilities; 5 import javax.swing.WindowConstants; 6 import java.awt.*; 7 import java.awt.event.WindowEvent; 8 import java.awt.event.WindowListener; 9 import java.awt.image.BufferedImage; 10 import java.io.File; 11 import java.io.IOException; 12 import java.lang.reflect.InvocationTargetException; 13 import java.util.Arrays; 14 15 /* @test 16 * @bug 8182638 17 * @summary [macosx] Active modal dialog is hidden by another non-active one 18 * @run main/othervm HiddenActiveModalTest 19 */ 20 21 22 // The test displays two modal dialogs one by one 23 // and checks that the latest modal dialog would be on top of all windows 24 public class HiddenActiveModalTest implements Runnable { 25 26 private static JFrame frame = new JFrame("HiddenActiveModalTest"); 27 28 private static boolean verbose = false; 29 private static boolean passed = true; 30 31 static DialogThread modalDialogThread1; 32 33 static DialogThread modalDialogThread2; 34 35 static class DialogThread { 36 37 JDialog dialog; 38 39 private String dialogTitle; 40 private Point location; 41 private int width; 42 private int height; 43 private DialogListener eventListener; 44 private Color c; 45 46 47 DialogThread(String dialogTitle, Point location, int width, int height, DialogListener eventListener, Color c) { 48 this.dialogTitle = dialogTitle; 49 this.location = location; 50 this.width = width; 51 this.height = height; 52 this.eventListener = eventListener; 53 this.c = c; 54 } 55 56 void run() { 57 dialog = new JDialog(frame, true); 58 dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); 59 dialog.getContentPane().setBackground(c); 60 dialog.setTitle(dialogTitle); 61 62 dialog.setLocation(location); 63 dialog.setSize(width, height); 64 65 if (eventListener != null) 66 dialog.addWindowListener(eventListener); 67 68 dialog.setVisible(true); 69 } 70 71 void removeWindowListener() { 72 dialog.removeWindowListener(eventListener); 73 } 74 } 75 76 static abstract class DialogListener implements WindowListener { 77 78 @Override 79 public void windowClosing(WindowEvent e) { 80 81 } 82 83 @Override 84 public void windowClosed(WindowEvent e) { 85 86 } 87 88 @Override 89 public void windowIconified(WindowEvent e) { 90 91 } 92 93 @Override 94 public void windowDeiconified(WindowEvent e) { 95 96 } 97 98 @Override 99 public void windowActivated(WindowEvent e) { 100 101 } 102 103 @Override 104 public void windowDeactivated(WindowEvent e) { 105 106 } 107 } 108 109 static class FirstDialogListener extends DialogListener { 110 @Override 111 public void windowOpened(WindowEvent windowEvent) { 112 modalDialogThread1.removeWindowListener(); 113 modalDialogThread2 = new DialogThread( 114 "Modal input 2", 115 new Point(5, 50), 116 300, 200, 117 new SecondDialogListener(), Color.GREEN); 118 modalDialogThread2.run(); 119 } 120 } 121 122 static class SecondDialogListener extends DialogListener { 123 @Override 124 public void windowOpened(WindowEvent windowEvent) { 125 try { 126 Robot robot = new Robot(); 127 Dimension shotSize = modalDialogThread2.dialog.getContentPane().getSize(); 128 Rectangle captureRect = new Rectangle(modalDialogThread2.dialog.getContentPane().getLocationOnScreen(), 129 shotSize); 130 131 try { 132 Thread.sleep(1000); 133 } catch (InterruptedException e) { 134 e.printStackTrace(); 135 } 136 137 BufferedImage screenImage = robot.createScreenCapture(captureRect); 138 139 int rgb; 140 int expectedRGB = Color.GREEN.getRGB(); 141 142 143 for (int row = 1; row < shotSize.height; row++) { 144 try { 145 // remove transparance 146 rgb = screenImage.getRGB(shotSize.width / 2, row); 147 148 if (verbose) { 149 System.out.print((rgb == expectedRGB) ? " ." : " " + Integer.toHexString(rgb)); 150 } 151 152 passed = passed & (expectedRGB == rgb); 153 154 } catch (ArrayIndexOutOfBoundsException e) { 155 throw new RuntimeException(e); 156 } 157 158 } 159 160 161 if (verbose) { 162 ImageIO.write(screenImage, "bmp", new File("test392.bmp")); 163 } 164 165 if (!passed) 166 throw new RuntimeException("The second dialog window was not on top"); 167 168 } catch (AWTException | IOException e) { 169 throw new RuntimeException(e); 170 } 171 modalDialogThread2.dialog.dispose(); 172 modalDialogThread1.dialog.dispose(); 173 frame.dispose(); 174 } 175 } 176 177 public void run() { 178 frame.setSize(350, 300); 179 frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 180 frame.setVisible(true); 181 182 modalDialogThread1 = new DialogThread( 183 "Modal input 1", 184 new Point(10, 75), 185 250, 150, 186 new FirstDialogListener(), Color.RED); 187 modalDialogThread1.run(); 188 } 189 190 public static void main(String[] args) throws Exception { 191 HiddenActiveModalTest.verbose = Arrays.asList(args).contains("-verbose"); 192 try { 193 SwingUtilities.invokeAndWait(new HiddenActiveModalTest()); 194 } catch (InterruptedException | InvocationTargetException e) { 195 throw new RuntimeException(e); 196 } 197 } 198 }