Skip to content

Commit 39d9c3b

Browse files
aghaisasJeanette Winzenburg
and
Jeanette Winzenburg
committedMay 5, 2020
8244110: NPE in MenuButtonSkinBase change listener
Co-authored-by: Jeanette Winzenburg <fastegal@openjdk.org> Reviewed-by: kcr, fastegal
1 parent 99f7747 commit 39d9c3b

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed
 

‎modules/javafx.controls/src/main/java/javafx/scene/control/skin/MenuButtonSkinBase.java

+17-3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.sun.javafx.scene.control.LabeledImpl;
3232
import com.sun.javafx.scene.control.skin.Utils;
3333
import javafx.application.Platform;
34+
import javafx.beans.value.ChangeListener;
3435
import javafx.collections.ListChangeListener;
3536
import javafx.event.ActionEvent;
3637
import javafx.scene.Node;
@@ -73,7 +74,7 @@ public class MenuButtonSkinBase<C extends MenuButton> extends SkinBase<C> {
7374
*/
7475
boolean behaveLikeButton = false;
7576
private ListChangeListener<MenuItem> itemsChangedListener;
76-
77+
private final ChangeListener<? super Scene> sceneChangeListener;
7778

7879

7980
/***************************************************************************
@@ -146,15 +147,18 @@ public MenuButtonSkinBase(final C control) {
146147
if (getSkinnable().getScene() != null) {
147148
ControlAcceleratorSupport.addAcceleratorsIntoScene(getSkinnable().getItems(), getSkinnable());
148149
}
149-
control.sceneProperty().addListener((scene, oldValue, newValue) -> {
150+
151+
sceneChangeListener = (scene, oldValue, newValue) -> {
150152
if (oldValue != null) {
151153
ControlAcceleratorSupport.removeAcceleratorsFromScene(getSkinnable().getItems(), oldValue);
152154
}
153155

156+
// FIXME: null skinnable should not happen
154157
if (getSkinnable() != null && getSkinnable().getScene() != null) {
155158
ControlAcceleratorSupport.addAcceleratorsIntoScene(getSkinnable().getItems(), getSkinnable());
156159
}
157-
});
160+
};
161+
control.sceneProperty().addListener(sceneChangeListener);
158162

159163
// Register listeners
160164
registerChangeListener(control.showingProperty(), e -> {
@@ -214,6 +218,16 @@ public MenuButtonSkinBase(final C control) {
214218

215219
/** {@inheritDoc} */
216220
@Override public void dispose() {
221+
// FIXME : JDK-8244112 - backout if we are already disposed
222+
// should check for getSkinnable to be null and return
223+
224+
// Cleanup accelerators
225+
if (getSkinnable().getScene() != null) {
226+
ControlAcceleratorSupport.removeAcceleratorsFromScene(getSkinnable().getItems(), getSkinnable().getScene());
227+
}
228+
229+
// Remove listeners
230+
getSkinnable().sceneProperty().removeListener(sceneChangeListener);
217231
getSkinnable().getItems().removeListener(itemsChangedListener);
218232
super.dispose();
219233
if (popup != null ) {

‎modules/javafx.controls/src/test/java/test/javafx/scene/control/MenuBarTest.java

+25-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,7 @@
4040
import javafx.scene.layout.VBox;
4141
import javafx.stage.Stage;
4242

43+
import org.junit.After;
4344
import org.junit.Before;
4445
import org.junit.Test;
4546

@@ -70,11 +71,34 @@ public class MenuBarTest {
7071
private Stage stage;
7172

7273
@Before public void setup() {
74+
setUncaughtExceptionHandler();
75+
7376
tk = (StubToolkit)Toolkit.getToolkit();
7477
menuBar = new MenuBar();
7578
menuBar.setUseSystemMenuBar(false);
7679
}
7780

81+
@After public void cleanup() {
82+
if (stage != null) {
83+
stage.hide();
84+
}
85+
removeUncaughtExceptionHandler();
86+
}
87+
88+
private void setUncaughtExceptionHandler() {
89+
Thread.currentThread().setUncaughtExceptionHandler((thread, throwable) -> {
90+
if (throwable instanceof RuntimeException) {
91+
throw (RuntimeException)throwable;
92+
} else {
93+
Thread.currentThread().getThreadGroup().uncaughtException(thread, throwable);
94+
}
95+
});
96+
}
97+
98+
private void removeUncaughtExceptionHandler() {
99+
Thread.currentThread().setUncaughtExceptionHandler(null);
100+
}
101+
78102
protected void startApp(Parent root) {
79103
scene = new Scene(root,800,600);
80104
stage = new Stage();
@@ -452,7 +476,6 @@ protected void startApp(Parent root) {
452476
}
453477

454478
@Test public void testKeyNavigationWithAllDisabledMenuItems() {
455-
456479
// Test key navigation with a single disabled menu in menubar
457480
VBox root = new VBox();
458481
Menu menu1 = new Menu("Menu1");

0 commit comments

Comments
 (0)
Please sign in to comment.