Skip to content

Commit 13ab2cb

Browse files
8252446: Screen.getScreens() is empty sometimes
Reviewed-by: arapte, pbansal
1 parent b2e2000 commit 13ab2cb

File tree

2 files changed

+105
-4
lines changed

2 files changed

+105
-4
lines changed

modules/javafx.graphics/src/main/java/javafx/stage/Screen.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,13 @@ private static void updateConfiguration() {
108108
if (newScreen != null) {
109109
if (canKeepOld) {
110110
canKeepOld = false;
111-
newScreens.clear();
112-
newScreens.addAll(Screen.screens.subList(0, i));
111+
newScreens.setAll(Screen.screens.subList(0, i));
113112
}
114113
newScreens.add(newScreen);
115114
}
116115
}
117116
if (!canKeepOld) {
118-
Screen.screens.clear();
119-
Screen.screens.addAll(newScreens);
117+
Screen.screens.setAll(newScreens);
120118
}
121119

122120
configurationDirty.set(false);
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
26+
package test.javafx.stage;
27+
28+
import java.util.concurrent.CountDownLatch;
29+
import java.util.concurrent.TimeUnit;
30+
import javafx.application.Platform;
31+
import javafx.collections.ListChangeListener.Change;
32+
import javafx.collections.ObservableList;
33+
import javafx.stage.Screen;
34+
import org.junit.AfterClass;
35+
import org.junit.BeforeClass;
36+
import org.junit.Test;
37+
import test.util.Util;
38+
39+
import static org.junit.Assert.*;
40+
import static org.junit.Assume.assumeTrue;
41+
42+
public class ScreenTest {
43+
static CountDownLatch startupLatch = new CountDownLatch(1);
44+
static ObservableList<Screen> screens;
45+
static volatile boolean screensListenerCalled = false;
46+
static volatile boolean screensSizeIsZero = false;
47+
48+
private static void waitForLatch(CountDownLatch latch, int seconds, String msg) throws Exception {
49+
assertTrue("Timeout: " + msg, latch.await(seconds, TimeUnit.SECONDS));
50+
}
51+
52+
/* This test for JDK-8252446 adds a listener on the ObservableList of
53+
* screens as the first thing in the platform startup runnable. Even
54+
* so, it cannot count on getting a call to the listener for the
55+
* initial list of screens. We don't get one on Windows or Linux. We
56+
* do get one on Mac, but this isn't guaranteed behavior, so this
57+
* test might or might not be effective.
58+
*/
59+
@BeforeClass
60+
public static void initFX() throws Exception {
61+
Platform.setImplicitExit(false);
62+
Platform.startup(() -> {
63+
screens = Screen.getScreens();
64+
screens.addListener((Change<?> change) -> {
65+
final int size = screens.size();
66+
System.err.println("Screens list changed, size = " + size);
67+
if (size == 0) {
68+
screensSizeIsZero = true;
69+
}
70+
screensListenerCalled = true;
71+
});
72+
Platform.runLater(startupLatch::countDown);
73+
});
74+
waitForLatch(startupLatch, 10, "FX runtime failed to start");
75+
}
76+
77+
@AfterClass
78+
public static void exitFX() {
79+
Platform.exit();
80+
}
81+
82+
@Test
83+
public void testScreensNotEmpty() {
84+
assertNotNull(screens);
85+
assertFalse("Screens list is empty", screens.size() == 0);
86+
}
87+
88+
@Test
89+
public void testScreensNotEmptyInListener() {
90+
// Sleep for some time to see whether we get an initial call to our
91+
// listener. Since we cannot count on the listener being called at
92+
// all, we can't use a latch.
93+
Util.sleep(2000);
94+
95+
// Skip the test if it isn't called.
96+
if (!screensListenerCalled) {
97+
System.err.println("Skipping test: Screens listener not called");
98+
}
99+
assumeTrue(screensListenerCalled);
100+
assertFalse("Screens list is empty in listener", screensSizeIsZero);
101+
}
102+
103+
}

0 commit comments

Comments
 (0)