带有 ChangeListener<Toggle> 的 ToggleGroup 总是向 oldValue 抛出空值
ToggleGroup with a ChangeListener<Toggle> always throws a null value to the oldValue
希望有人能帮助我。我在 javafx
中有 menu
和 2 RadioMenuItem
这样:
public class SiiController implements Initializable {
private ToggleGroup companyToggleGroup;
private RadioMenuItem companyARadio, companyBRadio;
private MenuBar menuBar;
private Menu fileMenu,companyMenu;
private Boolean checked;
@Override
public void initialize(URL url, ResourceBundle rb) {
/*......*/
companyMenu = new Menu("Companies");
companyToggleGroup = new ToggleGroup();
companyARadio= new RadioMenuItem("Company A");
companyARadio.setUserData("companya");
companyARadio.setToggleGroup(companyToggleGroup);
companyARadio.setSelected(true);
companyBRadio= new RadioMenuItem("Company B");
companyBRadio.setUserData("companyb");
companyBRadio.setToggleGroup(companyToggleGroup);
companyMenu.getItems().addAll(companyARadio, companyBRadio);
companyToggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
@Override
public void changed(ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) {
if(checked){
//do something
}else{
//remains the oldValue selected
//The next line is just for checking the old value
System.out.println("oldValue UserData"+oldValue.getUserData().toString());
}
}
});
}
menuBar.getMenus().addAll(fileMenu, companyMenu);
}
错误是监听器returns给Toggle oldValue
一个空值。我得到的例外是这个:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at controller.SiiController.changed(SiiController.java:284)
at controller.SiiController.changed(SiiController.java:280)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ReadOnlyObjectPropertyBase.fireValueChangedEvent(ReadOnlyObjectPropertyBase.java:74)
at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:102)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
at javafx.scene.control.ToggleGroup.set(ToggleGroup.java:137)
at javafx.scene.control.ToggleGroup.set(ToggleGroup.java:119)
at javafx.scene.control.ToggleGroup.selectToggle(ToggleGroup.java:149)
at javafx.scene.control.RadioMenuItem.invalidated(RadioMenuItem.java:195)
at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:109)
at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:144)
at javafx.scene.control.RadioMenuItem.setSelected(RadioMenuItem.java:180)
at javafx.scene.control.ToggleGroup.setSelected(ToggleGroup.java:166)
at javafx.scene.control.ToggleGroup.access0(ToggleGroup.java:54)
at javafx.scene.control.ToggleGroup.set(ToggleGroup.java:135)
at javafx.scene.control.ToggleGroup.set(ToggleGroup.java:119)
at javafx.scene.control.ToggleGroup.selectToggle(ToggleGroup.java:149)
at javafx.scene.control.RadioMenuItem.invalidated(RadioMenuItem.java:193)
at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:109)
at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:144)
at javafx.scene.control.RadioMenuItem.setSelected(RadioMenuItem.java:180)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1401)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren3(ContextMenuContent.java:1358)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access00(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent4(GlassViewEventHandler.java:417)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null8(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:748)
最后我想做的是,如果 Boolean checked
为假,则 ToggleGroup
上的先前选择保持不变。
非常感谢您的宝贵时间
你在监听器中试过这个吗:
if (oldValue != null) {
System.out.println("old value: " + oldValue.getUserData());
}
RadioMenuButton 会发生这种情况,但在使用 RadioButton 时会按预期工作。为此有一个bug report。
希望有人能帮助我。我在 javafx
中有 menu
和 2 RadioMenuItem
这样:
public class SiiController implements Initializable {
private ToggleGroup companyToggleGroup;
private RadioMenuItem companyARadio, companyBRadio;
private MenuBar menuBar;
private Menu fileMenu,companyMenu;
private Boolean checked;
@Override
public void initialize(URL url, ResourceBundle rb) {
/*......*/
companyMenu = new Menu("Companies");
companyToggleGroup = new ToggleGroup();
companyARadio= new RadioMenuItem("Company A");
companyARadio.setUserData("companya");
companyARadio.setToggleGroup(companyToggleGroup);
companyARadio.setSelected(true);
companyBRadio= new RadioMenuItem("Company B");
companyBRadio.setUserData("companyb");
companyBRadio.setToggleGroup(companyToggleGroup);
companyMenu.getItems().addAll(companyARadio, companyBRadio);
companyToggleGroup.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
@Override
public void changed(ObservableValue<? extends Toggle> observable, Toggle oldValue, Toggle newValue) {
if(checked){
//do something
}else{
//remains the oldValue selected
//The next line is just for checking the old value
System.out.println("oldValue UserData"+oldValue.getUserData().toString());
}
}
});
}
menuBar.getMenus().addAll(fileMenu, companyMenu);
}
错误是监听器returns给Toggle oldValue
一个空值。我得到的例外是这个:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at controller.SiiController.changed(SiiController.java:284)
at controller.SiiController.changed(SiiController.java:280)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ReadOnlyObjectPropertyBase.fireValueChangedEvent(ReadOnlyObjectPropertyBase.java:74)
at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:102)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
at javafx.scene.control.ToggleGroup.set(ToggleGroup.java:137)
at javafx.scene.control.ToggleGroup.set(ToggleGroup.java:119)
at javafx.scene.control.ToggleGroup.selectToggle(ToggleGroup.java:149)
at javafx.scene.control.RadioMenuItem.invalidated(RadioMenuItem.java:195)
at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:109)
at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:144)
at javafx.scene.control.RadioMenuItem.setSelected(RadioMenuItem.java:180)
at javafx.scene.control.ToggleGroup.setSelected(ToggleGroup.java:166)
at javafx.scene.control.ToggleGroup.access0(ToggleGroup.java:54)
at javafx.scene.control.ToggleGroup.set(ToggleGroup.java:135)
at javafx.scene.control.ToggleGroup.set(ToggleGroup.java:119)
at javafx.scene.control.ToggleGroup.selectToggle(ToggleGroup.java:149)
at javafx.scene.control.RadioMenuItem.invalidated(RadioMenuItem.java:193)
at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:109)
at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:144)
at javafx.scene.control.RadioMenuItem.setSelected(RadioMenuItem.java:180)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1401)
at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren3(ContextMenuContent.java:1358)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access00(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent4(GlassViewEventHandler.java:417)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null8(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:748)
最后我想做的是,如果 Boolean checked
为假,则 ToggleGroup
上的先前选择保持不变。
非常感谢您的宝贵时间
你在监听器中试过这个吗:
if (oldValue != null) {
System.out.println("old value: " + oldValue.getUserData());
}
RadioMenuButton 会发生这种情况,但在使用 RadioButton 时会按预期工作。为此有一个bug report。