Skip to content

Commit 5ac5d9e

Browse files
committed
WIP: Moved treeShowingProperty into its own class
1 parent c1b14de commit 5ac5d9e

File tree

6 files changed

+166
-114
lines changed

6 files changed

+166
-114
lines changed

modules/javafx.controls/src/main/java/javafx/scene/control/skin/ProgressIndicatorSkin.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
package javafx.scene.control.skin;
2727

2828
import com.sun.javafx.scene.NodeHelper;
29+
import com.sun.javafx.scene.TreeShowingExpression;
2930
import com.sun.javafx.scene.control.skin.Utils;
3031
import java.util.ArrayList;
3132
import java.util.Collections;
@@ -104,6 +105,7 @@ public class ProgressIndicatorSkin extends SkinBase<ProgressIndicator> {
104105
private IndeterminateSpinner spinner;
105106
private DeterminateIndicator determinateIndicator;
106107
private ProgressIndicator control;
108+
private TreeShowingExpression treeShowingExpression;
107109

108110
Animation indeterminateTransition;
109111

@@ -129,9 +131,11 @@ public ProgressIndicatorSkin(ProgressIndicator control) {
129131
// register listeners
130132
registerChangeListener(control.indeterminateProperty(), e -> initialize());
131133
registerChangeListener(control.progressProperty(), e -> updateProgress());
132-
registerChangeListener(NodeHelper.treeShowingProperty(control), e -> updateAnimation());
133134
registerChangeListener(control.sceneProperty(), e->updateAnimation());
134135

136+
treeShowingExpression = new TreeShowingExpression(control);
137+
treeShowingExpression.addListener((obs, old, current) -> updateAnimation());
138+
135139
initialize();
136140
updateAnimation();
137141
}
@@ -232,6 +236,8 @@ Paint getProgressColor() {
232236
@Override public void dispose() {
233237
super.dispose();
234238

239+
treeShowingExpression.dispose();
240+
235241
if (indeterminateTransition != null) {
236242
indeterminateTransition.stop();
237243
indeterminateTransition = null;

modules/javafx.graphics/src/main/java/com/sun/javafx/scene/NodeHelper.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,6 @@ public static boolean isTreeShowing(Node node) {
294294
return nodeAccessor.isTreeShowing(node);
295295
}
296296

297-
public static BooleanExpression treeShowingProperty(Node node) {
298-
return nodeAccessor.treeShowingProperty(node);
299-
}
300-
301297
public static List<Style> getMatchingStyles(CssMetaData cssMetaData, Styleable styleable) {
302298
return nodeAccessor.getMatchingStyles(cssMetaData, styleable);
303299
}
@@ -361,7 +357,6 @@ boolean doComputeIntersects(Node node, PickRay pickRay,
361357
boolean isTreeVisible(Node node);
362358
BooleanExpression treeVisibleProperty(Node node);
363359
boolean isTreeShowing(Node node);
364-
BooleanExpression treeShowingProperty(Node node);
365360
List<Style> getMatchingStyles(CssMetaData cssMetaData, Styleable styleable);
366361
Map<StyleableProperty<?>,List<Style>> findStyles(Node node,
367362
Map<StyleableProperty<?>,List<Style>> styleMap);
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* Copyright (c) 2013, 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 com.sun.javafx.scene;
27+
28+
import com.sun.javafx.binding.ExpressionHelper;
29+
import javafx.beans.InvalidationListener;
30+
import javafx.beans.binding.BooleanExpression;
31+
import javafx.beans.value.ChangeListener;
32+
import javafx.scene.Node;
33+
import javafx.scene.Scene;
34+
import javafx.stage.Window;
35+
36+
/**
37+
* Used to observe changes in tree showing status for a {@link Node}. For a Node's tree to be showing
38+
* it must be visible, its ancestors must be visible, the node must be part of a {@link Scene} and
39+
* the scene must have a {@link Window} which is currently showing.<p>
40+
*
41+
* This class provides the exact same functionality as {@link NodeHelper#isTreeShowing(Node)} in
42+
* an observable form.
43+
*/
44+
public class TreeShowingExpression extends BooleanExpression {
45+
private final ChangeListener<Boolean> windowShowingChangedListener = (obs, oldVal, newVal) -> updateTreeShowing();
46+
47+
private final ChangeListener<Window> sceneWindowChangedListener = (scene, oldWindow, newWindow) -> {
48+
if (oldWindow != null) {
49+
oldWindow.showingProperty().removeListener(windowShowingChangedListener);
50+
}
51+
if (newWindow != null) {
52+
newWindow.showingProperty().addListener(windowShowingChangedListener);
53+
}
54+
updateTreeShowing();
55+
};
56+
57+
private final ChangeListener<Scene> nodeSceneChangedListener = (node, oldScene, newScene) -> {
58+
if (oldScene != null) {
59+
oldScene.windowProperty().removeListener(sceneWindowChangedListener);
60+
}
61+
if (newScene != null) {
62+
newScene.windowProperty().addListener(sceneWindowChangedListener);
63+
}
64+
65+
sceneWindowChangedListener.changed(
66+
null,
67+
oldScene == null ? null : oldScene.getWindow(),
68+
newScene == null ? null : newScene.getWindow()
69+
);
70+
};
71+
72+
private final Node node;
73+
74+
private ExpressionHelper<Boolean> helper;
75+
private boolean valid;
76+
private boolean treeShowing;
77+
78+
/**
79+
* Constructs a new instance.
80+
*
81+
* @param node a {@link Node} for which the tree showing status should be observed, cannot be null
82+
*/
83+
public TreeShowingExpression(Node node) {
84+
this.node = node;
85+
this.node.sceneProperty().addListener(nodeSceneChangedListener);
86+
87+
NodeHelper.treeVisibleProperty(node).addListener(windowShowingChangedListener);
88+
89+
nodeSceneChangedListener.changed(null, null, node.getScene());
90+
}
91+
92+
/**
93+
* Cleans up any listeners that this class may have registered on the {@link Node}
94+
* that was supplied at construction.
95+
*/
96+
public void dispose() {
97+
node.sceneProperty().removeListener(nodeSceneChangedListener);
98+
99+
NodeHelper.treeVisibleProperty(node).removeListener(windowShowingChangedListener);
100+
}
101+
102+
private void updateTreeShowing() {
103+
boolean newValue = NodeHelper.isTreeShowing(node);
104+
105+
if (newValue != treeShowing) {
106+
treeShowing = newValue;
107+
invalidate();
108+
}
109+
}
110+
111+
@Override
112+
public void addListener(InvalidationListener listener) {
113+
helper = ExpressionHelper.addListener(helper, this, listener);
114+
}
115+
116+
@Override
117+
public void removeListener(InvalidationListener listener) {
118+
helper = ExpressionHelper.removeListener(helper, listener);
119+
}
120+
121+
@Override
122+
public void addListener(ChangeListener<? super Boolean> listener) {
123+
helper = ExpressionHelper.addListener(helper, this, listener);
124+
}
125+
126+
@Override
127+
public void removeListener(ChangeListener<? super Boolean> listener) {
128+
helper = ExpressionHelper.removeListener(helper, listener);
129+
}
130+
131+
protected void invalidate() {
132+
if (valid) {
133+
valid = false;
134+
ExpressionHelper.fireValueChangedEvent(helper);
135+
}
136+
}
137+
138+
@Override
139+
public boolean get() {
140+
if (!valid) {
141+
updateTreeShowing();
142+
valid = true;
143+
}
144+
145+
return treeShowing;
146+
}
147+
}

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

Lines changed: 1 addition & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -603,11 +603,6 @@ public boolean isTreeShowing(Node node) {
603603
return node.isTreeShowing();
604604
}
605605

606-
@Override
607-
public BooleanExpression treeShowingProperty(Node node) {
608-
return node.treeShowingProperty();
609-
}
610-
611606
@Override
612607
public List<Style> getMatchingStyles(CssMetaData cssMetaData,
613608
Styleable styleable) {
@@ -1006,20 +1001,6 @@ public String getName() {
10061001

10071002
private final InvalidationListener parentTreeVisibleChangedListener = valueModel -> updateTreeVisible(true);
10081003

1009-
private final ChangeListener<Boolean> windowShowingChangedListener
1010-
= (win, oldVal, newVal) -> updateTreeShowing();
1011-
1012-
private final ChangeListener<Window> sceneWindowChangedListener = (scene, oldWindow, newWindow) -> {
1013-
// Replace the windowShowingListener and call updateTreeShowing()
1014-
if (oldWindow != null) {
1015-
oldWindow.showingProperty().removeListener(windowShowingChangedListener);
1016-
}
1017-
if (newWindow != null) {
1018-
newWindow.showingProperty().addListener(windowShowingChangedListener);
1019-
}
1020-
updateTreeShowing();
1021-
};
1022-
10231004
private SubScene subScene = null;
10241005

10251006
/**
@@ -1081,26 +1062,6 @@ private void invalidatedScenes(Scene oldScene, SubScene oldSubScene) {
10811062
}
10821063
scenesChanged(newScene, newSubScene, oldScene, oldSubScene);
10831064

1084-
// isTreeShowing needs to take into account of Window's showing
1085-
if (oldScene != null) {
1086-
oldScene.windowProperty().removeListener(sceneWindowChangedListener);
1087-
1088-
Window window = oldScene.windowProperty().get();
1089-
if (window != null) {
1090-
window.showingProperty().removeListener(windowShowingChangedListener);
1091-
}
1092-
}
1093-
if (newScene != null) {
1094-
newScene.windowProperty().addListener(sceneWindowChangedListener);
1095-
1096-
Window window = newScene.windowProperty().get();
1097-
if (window != null) {
1098-
window.showingProperty().addListener(windowShowingChangedListener);
1099-
}
1100-
1101-
}
1102-
updateTreeShowing();
1103-
11041065
if (sceneChanged) reapplyCSS();
11051066

11061067
if (sceneChanged && !isDirtyEmpty()) {
@@ -8423,69 +8384,8 @@ private boolean isWindowShowing() {
84238384
return w != null && w.isShowing();
84248385
}
84258386

8426-
private void updateTreeShowing() {
8427-
setTreeShowing(isTreeVisible() && isWindowShowing());
8428-
}
8429-
8430-
private boolean treeShowing;
8431-
private TreeShowingPropertyReadOnly treeShowingRO;
8432-
8433-
final void setTreeShowing(boolean value) {
8434-
if (treeShowing != value) {
8435-
treeShowing = value;
8436-
((TreeShowingPropertyReadOnly) treeShowingProperty()).invalidate();
8437-
}
8438-
}
8439-
84408387
final boolean isTreeShowing() {
8441-
return treeShowingProperty().get();
8442-
}
8443-
8444-
final BooleanExpression treeShowingProperty() {
8445-
if (treeShowingRO == null) {
8446-
treeShowingRO = new TreeShowingPropertyReadOnly();
8447-
}
8448-
return treeShowingRO;
8449-
}
8450-
8451-
class TreeShowingPropertyReadOnly extends BooleanExpression {
8452-
8453-
private ExpressionHelper<Boolean> helper;
8454-
private boolean valid;
8455-
8456-
@Override
8457-
public void addListener(InvalidationListener listener) {
8458-
helper = ExpressionHelper.addListener(helper, this, listener);
8459-
}
8460-
8461-
@Override
8462-
public void removeListener(InvalidationListener listener) {
8463-
helper = ExpressionHelper.removeListener(helper, listener);
8464-
}
8465-
8466-
@Override
8467-
public void addListener(ChangeListener<? super Boolean> listener) {
8468-
helper = ExpressionHelper.addListener(helper, this, listener);
8469-
}
8470-
8471-
@Override
8472-
public void removeListener(ChangeListener<? super Boolean> listener) {
8473-
helper = ExpressionHelper.removeListener(helper, listener);
8474-
}
8475-
8476-
protected void invalidate() {
8477-
if (valid) {
8478-
valid = false;
8479-
ExpressionHelper.fireValueChangedEvent(helper);
8480-
}
8481-
}
8482-
8483-
@Override
8484-
public boolean get() {
8485-
valid = true;
8486-
return Node.this.treeShowing;
8487-
}
8488-
8388+
return isTreeVisible() && isWindowShowing();
84898389
}
84908390

84918391
private void updateTreeVisible(boolean parentChanged) {
@@ -8504,8 +8404,6 @@ && isDirty(DirtyBits.NODE_VISIBLE)) {
85048404
addToSceneDirtyList();
85058405
}
85068406
setTreeVisible(isTreeVisible);
8507-
8508-
updateTreeShowing();
85098407
}
85108408

85118409
private boolean treeVisible;

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,10 +306,9 @@ protected void invalidated() {
306306
"is already set as root of another scene or subScene");
307307
}
308308

309-
// disabled, isTreeVisible and isTreeShowing properties are inherited
309+
// disabled and isTreeVisible properties are inherited
310310
_value.setTreeVisible(isTreeVisible());
311311
_value.setDisabled(isDisabled());
312-
_value.setTreeShowing(isTreeShowing());
313312

314313
if (oldRoot != null) {
315314
StyleManager.getInstance().forget(SubScene.this);

0 commit comments

Comments
 (0)