diff --git a/modules/controls/src/main/java/com/sun/javafx/scene/control/ContextMenuContent.java b/modules/controls/src/main/java/com/sun/javafx/scene/control/ContextMenuContent.java --- a/modules/controls/src/main/java/com/sun/javafx/scene/control/ContextMenuContent.java +++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/ContextMenuContent.java @@ -50,7 +50,6 @@ import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.control.*; -import javafx.scene.control.skin.MenuBarSkin; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseEvent; import javafx.scene.input.ScrollEvent; @@ -1273,7 +1272,7 @@ label.setMouseTransparent(true); getChildren().add(label); - listener.unregisterChangeListener(focusedProperty()); + listener.unregisterChangeListeners(focusedProperty()); // RT-19546 update currentFocusedIndex when MenuItemContainer gets focused. // e.g this happens when you press the Right key to open a submenu; the first // menuitem is focused. @@ -1331,7 +1330,7 @@ addEventHandler(MouseEvent.MOUSE_RELEASED, mouseReleasedEventHandler); } else { // normal MenuItem // remove old listeners - listener.unregisterChangeListener(item.acceleratorProperty()); + listener.unregisterChangeListeners(item.acceleratorProperty()); // accelerator support updateAccelerator(); diff --git a/modules/controls/src/main/java/com/sun/javafx/scene/control/LambdaMultiplePropertyChangeListenerHandler.java b/modules/controls/src/main/java/com/sun/javafx/scene/control/LambdaMultiplePropertyChangeListenerHandler.java --- a/modules/controls/src/main/java/com/sun/javafx/scene/control/LambdaMultiplePropertyChangeListenerHandler.java +++ b/modules/controls/src/main/java/com/sun/javafx/scene/control/LambdaMultiplePropertyChangeListenerHandler.java @@ -71,13 +71,13 @@ } // need to be careful here - removing all listeners on the specific property! - public final Consumer> unregisterChangeListener(ObservableValue property) { + public final Consumer> unregisterChangeListeners(ObservableValue property) { if (propertyReferenceMap.containsKey(property)) { Consumer> consumer = propertyReferenceMap.remove(property); property.removeListener(weakPropertyChangedListener); return consumer; } - return null; + return o -> { }; } public void dispose() { diff --git a/modules/controls/src/main/java/javafx/scene/control/SkinBase.java b/modules/controls/src/main/java/javafx/scene/control/SkinBase.java --- a/modules/controls/src/main/java/javafx/scene/control/SkinBase.java +++ b/modules/controls/src/main/java/javafx/scene/control/SkinBase.java @@ -26,9 +26,6 @@ package javafx.scene.control; import com.sun.javafx.scene.control.LambdaMultiplePropertyChangeListenerHandler; -import com.sun.javafx.scene.control.behavior.BehaviorBase; -import javafx.application.ConditionalFeature; -import javafx.application.Platform; import javafx.beans.value.ObservableValue; import javafx.css.CssMetaData; import javafx.css.PseudoClass; @@ -213,6 +210,25 @@ lambdaChangeListenerHandler.registerChangeListener(property, consumer); } + /** + * Unregisters all change listeners that have been registered using {@link #registerChangeListener(ObservableValue, Consumer)} + * for the given property. The end result is that the given property is no longer observed by any of the change + * listeners, but it may still have additional listeners registered on it through means outside of + * {@link #registerChangeListener(ObservableValue, Consumer)}. + * + * @param property The property for which all listeners should be removed. + * @return A single chained {@link Consumer} consisting of all {@link Consumer consumers} registered through + * {@link #registerChangeListener(ObservableValue, Consumer)}. If no consumers have been registered on this + * property, a no-op Consumer will be returned. + * @since 9 + */ + protected final Consumer> unregisterChangeListeners(ObservableValue property) { + if (lambdaChangeListenerHandler == null) { + return o -> { }; + } + return lambdaChangeListenerHandler.unregisterChangeListeners(property); + } +