11/*
2- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
2121 * questions.
2222 */
2323
24- /**
25- * @test @summary setAlwaysOnTop doesn't behave correctly in Linux/Solaris under
26- * certain scenarios
24+ /*
25+ * @test
26+ * @key headful
2727 * @bug 8021961
28- * @author Semyon Sadetsky
29- * @run main ChildAlwaysOnTopTest
28+ * @summary To test setAlwaysOnTop functionality.
29+ * @run main/othervm -Dsun.java2d.uiScale=1 ChildAlwaysOnTopTest
3030 */
3131
32- import javax .swing .*;
33- import java .awt .*;
32+ import java .awt .Color ;
33+ import java .awt .Dialog ;
34+ import java .awt .Frame ;
35+ import java .awt .Window ;
36+ import java .awt .Rectangle ;
37+ import java .awt .Robot ;
38+ import java .awt .Panel ;
39+ import java .awt .Point ;
40+ import java .awt .Toolkit ;
41+ import java .awt .image .BufferedImage ;
42+
43+ import java .io .File ;
44+ import java .io .IOException ;
45+ import javax .imageio .ImageIO ;
46+
47+ import javax .swing .JDialog ;
48+ import javax .swing .JLabel ;
49+ import javax .swing .SwingUtilities ;
3450
3551public class ChildAlwaysOnTopTest {
3652
3753 private static Window win1 ;
3854 private static Window win2 ;
3955 private static Point point ;
56+ private static Robot robot ;
57+ private static int caseNo = 0 ;
58+ private static StringBuffer errorLog = new StringBuffer ();
59+ private static String [] errorMsg = new String [] {
60+ " Scenario 1 Failed: alwaysOnTop window is sent back by another" +
61+ " child window with setVisible()." ,
62+ " Scenario 2 Failed: alwaysOnTop window is" +
63+ " sent back by another child window with toFront()." ,
64+ " Scenario 3 Failed: Failed to unset alwaysOnTop " ,
65+ };
4066
4167 public static void main (String [] args ) throws Exception {
42- if ( Toolkit .getDefaultToolkit ().isAlwaysOnTopSupported () ) {
4368
69+ if (!Toolkit .getDefaultToolkit ().isAlwaysOnTopSupported ()) {
70+ System .out .println ("alwaysOnTop not supported by: " +
71+ Toolkit .getDefaultToolkit ().getClass ().getName ());
72+ return ;
73+ }
4474
45- test (null );
75+ // CASE 1 - JDialog without parent/owner
76+ System .out .println ("Testing CASE 1: JDialog without parent/owner" );
77+ caseNo = 1 ;
78+ test (null );
79+ System .out .println ("CASE 1 Completed" );
80+ System .out .println ();
4681
47- Window f = new Frame ();
48- f .setBackground (Color .darkGray );
49- f .setSize (500 , 500 );
50- try {
51- test (f );
52- } finally {
53- f .dispose ();
54- }
82+ // CASE 2 - JDialog with JFrame as owner
83+ System .out .println ("Testing CASE 2: JDialog with JFrame as owner" );
84+ caseNo = 2 ;
85+ Window f = new Frame ();
86+ f .setBackground (Color .darkGray );
87+ f .setSize (500 , 500 );
88+ try {
89+ test (f );
90+ } finally {
91+ f .dispose ();
92+ }
93+ System .out .println ("CASE 2 Completed" );
94+ System .out .println ();
5595
56- f = new Frame ();
57- f .setBackground (Color .darkGray );
58- f .setSize (500 , 500 );
59- f .setVisible (true );
60- f = new Dialog ((Frame )f );
61- try {
62- test (f );
63- } finally {
64- ((Frame )f .getParent ()).dispose ();
65- }
96+ // CASE 3 - JDialog within another JDialog as owner
97+ System .out .println ("Testing CASE 3:Dialog within another" +
98+ " JDialog as owner" );
99+ caseNo = 3 ;
100+ f = new Frame ();
101+ f .setBackground (Color .darkGray );
102+ f .setSize (500 , 500 );
103+ f .setVisible (true );
104+ f = new Dialog ((Frame )f );
105+ try {
106+ test (f );
107+ } finally {
108+ ((Frame )f .getParent ()).dispose ();
109+ }
110+ System .out .println ("CASE 3 Completed" );
111+ System .out .println ();
112+
113+ if (errorLog .length () == 0 ) {
114+ System .out .println ("All three cases passed !!" );
115+ }
116+ else {
117+ throw new RuntimeException ("Following cases and scenarios failed." +
118+ " Please check the saved screenshots.\n " + errorLog );
66119 }
67- System .out .println ("ok" );
68120 }
69121
70122 public static void test (Window parent ) throws Exception {
71- SwingUtilities .invokeAndWait (new Runnable () {
72- @ Override
73- public void run () {
74- win1 = parent == null ? new JDialog () : new JDialog (parent );
75- win1 .setName ("top" );
76- win2 = parent == null ? new JDialog () : new JDialog (parent );
77- win2 .setName ("behind" );
78- win1 .setSize (200 , 200 );
79- Panel panel = new Panel ();
80- panel .setBackground (Color .GREEN );
81- win1 .add (panel );
82- panel = new Panel ();
83- panel .setBackground (Color .RED );
84- win2 .add (panel );
85- win1 .setAlwaysOnTop (true );
86- win2 .setAlwaysOnTop (false );
87- win1 .setVisible (true );
88- }
89- });
123+ try {
124+ SwingUtilities .invokeAndWait (new Runnable () {
125+ @ Override
126+ public void run () {
127+ win1 = parent == null ? new JDialog () : new JDialog (parent );
128+ win1 .setName ("Top" );
90129
91- Robot robot = new Robot ();
92- robot .delay (200 );
93- robot .waitForIdle ();
130+ win2 = parent == null ? new JDialog () : new JDialog (parent );
131+ win2 .setName ("Behind" );
132+
133+ JLabel label = new JLabel ("TOP WINDOW" );
134+ // top window - green and smaller
135+ win1 .setSize (200 , 200 );
136+ Panel panel = new Panel ();
137+ panel .setBackground (Color .GREEN );
138+ panel .add (label );
139+ win1 .add (panel );
140+ win1 .setAlwaysOnTop (true );
94141
95- SwingUtilities .invokeAndWait (new Runnable () {
96- @ Override
97- public void run () {
142+ // behind window - red and bigger
143+ label = new JLabel ("BEHIND WINDOW" );
144+ win2 .setSize (300 , 300 );
145+ panel = new Panel ();
146+ panel .setBackground (Color .RED );
147+ panel .add (label );
148+ win2 .add (panel );
149+
150+ win1 .setVisible (true );
151+ win2 .setVisible (true );
152+ }
153+ });
154+
155+ robot = new Robot ();
156+ robot .setAutoDelay (300 );
157+ robot .waitForIdle ();
158+
159+ // Scenario 1: Trying to unset the alwaysOnTop (green window)
160+ // by setting the setVisible to true for behind (red) window
161+ System .out .println (" >> Testing Scenario 1 ..." );
162+ SwingUtilities .invokeAndWait (()-> {
98163 point = win1 .getLocationOnScreen ();
99- win2 .setBounds (win1 .getBounds ());
100164 win2 .setVisible (true );
101- }
102- });
165+ });
103166
104- robot .delay (200 );
105- robot .waitForIdle ();
167+ checkTopWindow (caseNo , 1 , Color .GREEN );
106168
107- Color color = robot .getPixelColor (point .x + 100 , point .y + 100 );
108- if (!color .equals (Color .GREEN )) {
109- win1 .dispose ();
110- win2 .dispose ();
111- throw new RuntimeException ("alawaysOnTop window is sent back by " +
112- "another child window setVisible(). " + color );
113- }
169+ /*---------------------------------------------------------------*/
114170
115- SwingUtilities .invokeAndWait (new Runnable () {
116- @ Override
117- public void run () {
171+ // Scenario 2: Trying to unset the alwaysOnTop (green window)
172+ // by setting toFront() to true for behind (red) window
173+ System .out .println (" >> Testing Scenario 2 ..." );
174+ SwingUtilities .invokeAndWait (()-> {
118175 win2 .toFront ();
119176 if (parent != null ) {
120177 parent .setLocation (win1 .getLocation ());
121178 parent .toFront ();
122179 }
123- }
124- });
180+ });
125181
126- robot .delay (200 );
127- robot .waitForIdle ();
182+ checkTopWindow (caseNo , 2 , Color .GREEN );
128183
129- color = robot .getPixelColor (point .x + 100 , point .y + 100 );
130- if (!color .equals (Color .GREEN )) {
131- win1 .dispose ();
132- win2 .dispose ();
133- throw new RuntimeException ("alawaysOnTop window is sent back by " +
134- "another child window toFront(). " + color );
135- }
184+ /*----------------------------------------------------------------*/
136185
137- SwingUtilities .invokeAndWait (new Runnable () {
138- @ Override
139- public void run () {
140- win1 .setAlwaysOnTop (false );
141- if (parent != null ) {
142- parent .setVisible (false );
143- parent .setVisible (true );
186+ // Scenario 3: Trying to unset the alwaysOnTop (green window)
187+ // by setting alwaysOnTop to false. The unsetting should work
188+ // in this case and bring the red window to the top.
189+ System .out .println (" >> Testing Scenario 3 ..." );
190+ SwingUtilities .invokeAndWait (new Runnable () {
191+ @ Override
192+ public void run () {
193+ win1 .setAlwaysOnTop (false );
194+ if (parent != null ) {
195+ parent .setVisible (false );
196+ parent .setVisible (true );
197+ }
144198 }
145- win2 .toFront ();
199+ });
200+
201+ robot .delay (300 );
202+ robot .waitForIdle ();
203+
204+ SwingUtilities .invokeAndWait (new Runnable () {
205+ @ Override
206+ public void run () {
207+ win2 .toFront ();
208+ }
209+ });
210+
211+ checkTopWindow (caseNo , 3 , Color .RED );
212+
213+ } finally {
214+ if (win1 != null ) {
215+ SwingUtilities .invokeAndWait (()-> win1 .dispose ());
216+ }
217+ if (win2 != null ) {
218+ SwingUtilities .invokeAndWait (()-> win2 .dispose ());
146219 }
147- });
220+ }
221+ }
222+ // to check if the current top window background color
223+ // matches the expected color
224+ private static void checkTopWindow (int caseNo , int scenarioNo ,
225+ Color expectedColor ) {
148226
149- robot .delay (200 );
227+ robot .delay (500 );
150228 robot .waitForIdle ();
229+ Color actualColor = robot .getPixelColor (point .x + 100 , point .y + 100 );
151230
152- color = robot .getPixelColor (point .x + 100 , point .y + 100 );
153- if (!color .equals (Color .RED )) {
154- throw new RuntimeException ("Failed to unset alawaysOnTop " + color );
231+ saveScreenCapture (caseNo , scenarioNo );
232+
233+ if (!actualColor .equals (expectedColor )) {
234+ System .out .println (" >> Scenario " + scenarioNo +" FAILED !!" );
235+ errorLog .append ("Case " + caseNo + errorMsg [scenarioNo - 1 ]
236+ +" Expected Color: " + expectedColor +" vs Actual Color: "
237+ + actualColor +"\n " );
238+ }
239+ else {
240+ System .out .println (" >> Scenario " + scenarioNo +" Passed" );
155241 }
242+ }
156243
157- win1 .dispose ();
158- win2 .dispose ();
244+ // For Debugging purpose - method used to save the screen capture as
245+ // BufferedImage in the event the test fails
246+ private static void saveScreenCapture (int caseNo , int scenarioNo ) {
247+ String filename = "img_" + caseNo +"_" + scenarioNo ;
248+ BufferedImage image = robot .createScreenCapture (
249+ new Rectangle (0 , 0 , 500 , 500 ));
250+ try {
251+ ImageIO .write (image , "png" , new File (filename ));
252+ } catch (IOException e ) {
253+ e .printStackTrace ();
254+ }
159255 }
160- }
256+ }
0 commit comments