diff --git a/modules/controls/src/main/java/javafx/scene/control/PopupControl.java b/modules/controls/src/main/java/javafx/scene/control/PopupControl.java --- a/modules/controls/src/main/java/javafx/scene/control/PopupControl.java +++ b/modules/controls/src/main/java/javafx/scene/control/PopupControl.java @@ -30,6 +30,7 @@ import java.util.List; import javafx.application.Application; +import javafx.application.Platform; import javafx.beans.property.DoubleProperty; import javafx.beans.property.DoublePropertyBase; import javafx.beans.property.ObjectProperty; @@ -111,7 +112,12 @@ super(); this.bridge = new CSSBridge(); setAnchorLocation(AnchorLocation.CONTENT_TOP_LEFT); - getContent().add(bridge); + + if (Platform.isFxApplicationThread()) { + getContent().add(bridge); + } else { + Platform.runLater(() -> getContent().add(bridge)); + } } // TODO the fact that PopupWindow uses a group for auto-moving things diff --git a/modules/controls/src/main/java/javafx/scene/control/Tooltip.java b/modules/controls/src/main/java/javafx/scene/control/Tooltip.java --- a/modules/controls/src/main/java/javafx/scene/control/Tooltip.java +++ b/modules/controls/src/main/java/javafx/scene/control/Tooltip.java @@ -27,6 +27,7 @@ import com.sun.javafx.css.StyleManager; +import javafx.application.Platform; import javafx.css.SimpleStyleableBooleanProperty; import javafx.css.SimpleStyleableDoubleProperty; import javafx.css.SimpleStyleableObjectProperty; @@ -158,7 +159,13 @@ super(); if (text != null) setText(text); bridge = new CSSBridge(); - getContent().setAll(bridge); + + if (Platform.isFxApplicationThread()) { + getContent().setAll(bridge); + } else { + Platform.runLater(() -> getContent().setAll(bridge)); + } + getStyleClass().setAll("tooltip"); } diff --git a/modules/graphics/src/main/java/javafx/stage/PopupWindow.java b/modules/graphics/src/main/java/javafx/stage/PopupWindow.java --- a/modules/graphics/src/main/java/javafx/stage/PopupWindow.java +++ b/modules/graphics/src/main/java/javafx/stage/PopupWindow.java @@ -30,6 +30,7 @@ import java.util.ArrayList; import java.util.List; +import javafx.application.Platform; import javafx.beans.InvalidationListener; import javafx.beans.Observable; import javafx.beans.property.BooleanProperty; @@ -63,6 +64,8 @@ import com.sun.javafx.stage.WindowEventDispatcher; import com.sun.javafx.tk.Toolkit; import java.security.AllPermission; +import java.util.concurrent.CountDownLatch; + import javafx.beans.property.ObjectPropertyBase; import javafx.beans.property.ReadOnlyObjectProperty; import javafx.beans.property.ReadOnlyObjectWrapper; @@ -134,7 +137,17 @@ private WeakChangeListener weakOwnerNodeListener = new WeakChangeListener(changeListener); + private final CountDownLatch sceneLatch = new CountDownLatch(1); + public PopupWindow() { + if (Platform.isFxApplicationThread()) { + initScene(); + } else { + Platform.runLater(() -> initScene()); + } + } + + private void initScene() { final Pane popupRoot = new Pane(); popupRoot.setBackground(Background.EMPTY); popupRoot.getStyleClass().add("popup"); @@ -145,6 +158,7 @@ popupRoot.layoutBoundsProperty().addListener(popupWindowUpdater); popupRoot.boundsInLocalProperty().addListener(popupWindowUpdater); + scene.rootProperty().addListener( new InvalidationListener() { private Node oldRoot = scene.getRoot(); @@ -177,6 +191,8 @@ } } }); + + sceneLatch.countDown(); } /** @@ -189,7 +205,7 @@ */ @Deprecated protected ObservableList getContent() { - final Parent rootNode = getScene().getRoot(); + final Parent rootNode = getPopupWindowScene().getRoot(); if (rootNode instanceof Group) { return ((Group) rootNode).getChildren(); } @@ -241,6 +257,15 @@ throw new UnsupportedOperationException(); } + private Scene getPopupWindowScene() { + try { + sceneLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return getScene(); + } + /** * This convenience variable indicates whether, when the popup is shown, * it should automatically correct its position such that it doesn't end @@ -426,7 +451,7 @@ owner.showingProperty().addListener(weakOwnerNodeListener); } - final Scene sceneValue = getScene(); + final Scene sceneValue = getPopupWindowScene(); SceneHelper.parentEffectiveOrientationInvalidated(sceneValue); // RT-28447 @@ -681,7 +706,7 @@ private Bounds getExtendedBounds() { if (cachedExtendedBounds == null) { - final Parent rootNode = getScene().getRoot(); + final Parent rootNode = getPopupWindowScene().getRoot(); cachedExtendedBounds = union(rootNode.getLayoutBounds(), rootNode.getBoundsInLocal()); } @@ -692,7 +717,7 @@ private Bounds getAnchorBounds() { if (cachedAnchorBounds == null) { cachedAnchorBounds = getAnchorLocation().isContentLocation() - ? getScene().getRoot() + ? getPopupWindowScene().getRoot() .getLayoutBounds() : getExtendedBounds(); } @@ -703,7 +728,7 @@ private void updateWindow(final double newAnchorX, final double newAnchorY) { final AnchorLocation anchorLocationValue = getAnchorLocation(); - final Parent rootNode = getScene().getRoot(); + final Parent rootNode = getPopupWindowScene().getRoot(); final Bounds extendedBounds = getExtendedBounds(); final Bounds anchorBounds = getAnchorBounds();