Skip to content

Commit 93de584

Browse files
committed
8266966: Wrong CSS properties are applied to other nodes after fix for JDK-8204568
Reviewed-by: jpereda, kcr
1 parent c511789 commit 93de584

File tree

3 files changed

+132
-3
lines changed

3 files changed

+132
-3
lines changed

modules/javafx.graphics/src/main/java/javafx/scene/CssStyleHelper.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -453,12 +453,15 @@ private StyleMap getStyleMap(Styleable styleable) {
453453
private boolean forceSlowpath = false;
454454
}
455455

456+
private boolean resetInProgress = false;
457+
456458
private void resetToInitialValues(final Styleable styleable) {
457459

458460
if (cacheContainer == null ||
459461
cacheContainer.cssSetProperties == null ||
460462
cacheContainer.cssSetProperties.isEmpty()) return;
461463

464+
resetInProgress = true;
462465
// RT-31714 - make a copy of the entry set and clear the cssSetProperties immediately.
463466
Set<Entry<CssMetaData, CalculatedValue>> entrySet = new HashSet<>(cacheContainer.cssSetProperties.entrySet());
464467
cacheContainer.cssSetProperties.clear();
@@ -474,6 +477,7 @@ private void resetToInitialValues(final Styleable styleable) {
474477
styleableProperty.applyStyle(calculatedValue.getOrigin(), calculatedValue.getValue());
475478
}
476479
}
480+
resetInProgress = false;
477481
}
478482

479483

@@ -589,9 +593,20 @@ private Set<PseudoClass>[] getTransitionStates(final Node node) {
589593
// Any modifications to the method transitionToState() should be applied here if needed.
590594
void recalculateRelativeSizeProperties(final Node node, Font fontForRelativeSizes) {
591595

592-
if (transitionStateInProgress) {
593-
// If transitionToState() is being executed for the current control then all the css properties will get
594-
// calculated there, and so we need to do anything here.
596+
if (transitionStateInProgress || resetInProgress) {
597+
// It is not required to recalculate the relative sized properties,
598+
// 1. [transitionStateInProgress]: if transitionToState() is being executed for the current control then all
599+
// the css properties will get calculated there, OR
600+
// 2. [resetInProgress]: if resetToInitialValues() is being executed, which sets font to default font.
601+
// The css style set by user if any is applied post this reset which calls
602+
// recalculateRelativeSizeProperties() again.
603+
// JDK-8266966: StyleManager.styleMapList stores the StyleMaps of nodes using an id as key.
604+
// Each node stores this id in CssStyleHelper.CacheContainer.smapId
605+
// CssStyleHelper.getStyleMap(node) gets a StyleMap from StyleManager.styleMapList by using the
606+
// CssStyleHelper.CacheContainer.smapId as key.
607+
// When resetToInitialValues() is in progress, the StyleManager.styleMapList gets updated, therefore
608+
// calls to getStyleMap(node) should be avoided, as it may return an incorrect StyleMap for a given node.
609+
595610
return;
596611
}
597612
if (cacheContainer == null) {
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright (c) 2021, 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.scene;
27+
28+
import javafx.application.Application;
29+
import javafx.application.Platform;
30+
import javafx.scene.Scene;
31+
import javafx.scene.control.Label;
32+
import javafx.scene.control.Button;
33+
import javafx.scene.control.CheckBox;
34+
import javafx.scene.layout.StackPane;
35+
import javafx.stage.Stage;
36+
37+
import java.util.concurrent.CountDownLatch;
38+
import java.util.concurrent.TimeUnit;
39+
40+
import junit.framework.Assert;
41+
import org.junit.AfterClass;
42+
import org.junit.BeforeClass;
43+
import org.junit.Test;
44+
import test.util.Util;
45+
import static org.junit.Assert.assertTrue;
46+
47+
public class CssStyleHelperTest {
48+
49+
private static CountDownLatch startupLatch;
50+
private static StackPane root;
51+
private static Stage stage;
52+
private static Label label1;
53+
private static Button button;
54+
private static CheckBox checkBox;
55+
private static Label label2;
56+
57+
public static class TestApp extends Application {
58+
@Override
59+
public void start(Stage primaryStage) throws Exception {
60+
stage = primaryStage;
61+
label1 = new Label("Label1");
62+
button = new Button("aButton");
63+
checkBox = new CheckBox("aCheckBox");
64+
label2 = new Label("Label2");
65+
66+
root = new StackPane();
67+
root.getChildren().addAll(label1, button, checkBox, label2);
68+
Scene scene = new Scene(root, 200, 200);
69+
scene.getStylesheets().add(getClass().getResource("RootFont.css").toExternalForm());
70+
primaryStage.setScene(scene);
71+
primaryStage.setOnShown(l -> {
72+
Platform.runLater(() -> startupLatch.countDown());
73+
});
74+
primaryStage.show();
75+
}
76+
}
77+
78+
@BeforeClass
79+
public static void initFX() throws Exception {
80+
startupLatch = new CountDownLatch(1);
81+
new Thread(() -> Application.launch(TestApp.class, (String[]) null)).start();
82+
assertTrue("Timeout waiting for FX runtime to start",
83+
startupLatch.await(15, TimeUnit.SECONDS));
84+
}
85+
86+
@Test
87+
public void testCssIsCorrectlyAppliedToLabelOnStageHideAndShow() throws Exception {
88+
// sanity
89+
Assert.assertNull("Label1 should have no background", label1.getBackground());
90+
Assert.assertNull("Label2 should have no background", label2.getBackground());
91+
92+
startupLatch = new CountDownLatch(1);
93+
Util.runAndWait(() -> {
94+
stage.hide();
95+
stage.show();
96+
});
97+
assertTrue("Timeout waiting for Stage to show after hide",
98+
startupLatch.await(15, TimeUnit.SECONDS));
99+
100+
Assert.assertNull("Label1 should have no background", label1.getBackground());
101+
Assert.assertNull("Label2 should have no background", label2.getBackground());
102+
}
103+
104+
@AfterClass
105+
public static void teardownOnce() {
106+
Platform.runLater(() -> {
107+
stage.hide();
108+
Platform.exit();
109+
});
110+
}
111+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.root {
2+
-fx-font-size: 50px;
3+
}

0 commit comments

Comments
 (0)