diff --git a/modules/javafx.controls/src/main/java/javafx/scene/control/ContextMenu.java b/modules/javafx.controls/src/main/java/javafx/scene/control/ContextMenu.java index 1c90448cc72..db9b29b066b 100644 --- a/modules/javafx.controls/src/main/java/javafx/scene/control/ContextMenu.java +++ b/modules/javafx.controls/src/main/java/javafx/scene/control/ContextMenu.java @@ -25,6 +25,8 @@ package javafx.scene.control; +import javafx.geometry.Bounds; +import javafx.geometry.NodeOrientation; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectPropertyBase; import javafx.collections.ListChangeListener.Change; @@ -44,6 +46,7 @@ import com.sun.javafx.collections.TrackableObservableList; import com.sun.javafx.tk.Toolkit; import com.sun.javafx.util.Utils; +import com.sun.javafx.stage.PopupWindowHelper; /** *
@@ -249,10 +252,10 @@ public void show(Node anchor, Side side, double dx, double dy) {
if (anchor == null) return;
if (getItems().size() == 0) return;
+ PopupWindowHelper.ownerWindow(this).set(anchor.getScene().getWindow());
+ PopupWindowHelper.ownerNode(this).set(anchor);
+ PopupWindowHelper.applyStylesheetFromOwner(this, anchor.getScene().getWindow());
getScene().setNodeOrientation(anchor.getEffectiveNodeOrientation());
- if (getScene().getStylesheets().isEmpty()) {
- getScene().getStylesheets().setAll(anchor.getScene().getStylesheets());
- }
HPos hpos = side == Side.LEFT ? HPos.LEFT : side == Side.RIGHT ? HPos.RIGHT : HPos.CENTER;
VPos vpos = side == Side.TOP ? VPos.TOP : side == Side.BOTTOM ? VPos.BOTTOM : VPos.CENTER;
diff --git a/modules/javafx.controls/src/test/java/test/javafx/scene/control/ContextMenuTest.java b/modules/javafx.controls/src/test/java/test/javafx/scene/control/ContextMenuTest.java
index 865850a11f9..dd20218f9d6 100644
--- a/modules/javafx.controls/src/test/java/test/javafx/scene/control/ContextMenuTest.java
+++ b/modules/javafx.controls/src/test/java/test/javafx/scene/control/ContextMenuTest.java
@@ -36,6 +36,7 @@
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Optional;
+import java.util.concurrent.atomic.AtomicInteger;
import javafx.css.PseudoClass;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
@@ -51,6 +52,7 @@
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
+import javafx.scene.control.skin.ButtonSkin;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
@@ -64,6 +66,7 @@
import test.com.sun.javafx.scene.control.infrastructure.KeyEventFirer;
import test.com.sun.javafx.scene.control.infrastructure.MouseEventFirer;
import test.com.sun.javafx.scene.control.infrastructure.StageLoader;
+import test.javafx.scene.CssStyleHelperTest;
public class ContextMenuTest {
@@ -695,6 +698,30 @@ private ContextMenu createContextMenuAndShowSubMenu() {
assertEquals(anchorBounds.getMinY(), cmBounds.getMinY(), 0.0);
}
+ @Test public void testCssProcessedOnlyOnce() {
+ String css = """
+ .button { -fx-skin: "test.javafx.scene.control.ContextMenuTest$ButtonSkin1"; }
+ .anchor .button { -fx-skin: "st.javafx.scene.control.ContextMenuTest$ButtonSkin2"; }
+ """;
+ anchorBtn.getScene().getStylesheets().add(CssStyleHelperTest.toDataURL(css));
+ anchorBtn.getStyleClass().add("anchor");
+ AtomicInteger skinCounter = new AtomicInteger(0);
+ Button button = new Button();
+ button.skinProperty().subscribe((oldSkin, newSkin) -> {
+ skinCounter.incrementAndGet();
+ });
+ menuItem.setGraphic(button);
+ ContextMenu cm = createContextMenu(false);
+ cm.show(anchorBtn, Side.TOP, 0, 0);
+
+ Bounds anchorBounds = anchorBtn.localToScreen(anchorBtn.getLayoutBounds());
+ Node cmNode = cm.getScene().getRoot();
+ Bounds cmBounds = cm.getScene().getRoot().localToScreen(cmNode.getLayoutBounds());
+
+ assertEquals(anchorBounds.getMinX(), cmBounds.getMinX(), 0.0);
+ assertEquals(anchorBounds.getMinY(), cmBounds.getMaxY(), 0.0);
+ assertEquals(1, skinCounter.get());
+ }
@Test public void test_position_withCSS() {
anchorBtn.getScene().getStylesheets().add(
@@ -775,4 +802,11 @@ private ContextMenu createContextMenuAndShowSubMenu() {
assertEquals(0, padding.getLeft(), 0.0);
anchorBtn.setGraphic(null);
}
+
+ public static class ButtonSkin1 extends ButtonSkin {
+ public ButtonSkin1(Button button) { super(button); }
+ }
+ public static class ButtonSkin2 extends ButtonSkin {
+ public ButtonSkin2(Button button) { super(button); }
+ }
}
diff --git a/modules/javafx.graphics/src/main/java/com/sun/javafx/stage/PopupWindowHelper.java b/modules/javafx.graphics/src/main/java/com/sun/javafx/stage/PopupWindowHelper.java
index e7d882ff060..df0e9ab16a0 100644
--- a/modules/javafx.graphics/src/main/java/com/sun/javafx/stage/PopupWindowHelper.java
+++ b/modules/javafx.graphics/src/main/java/com/sun/javafx/stage/PopupWindowHelper.java
@@ -27,6 +27,7 @@
import com.sun.javafx.util.Utils;
import javafx.collections.ObservableList;
+import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.scene.Node;
import javafx.stage.PopupWindow;
import javafx.stage.Window;
@@ -67,6 +68,14 @@ public static void applyStylesheetFromOwner(PopupWindow popupWindow, Window owne
popupWindowAccessor.applyStylesheetFromOwner(popupWindow, owner);
}
+ public static ReadOnlyObjectWrapper