JavaFX ComboBox setItems触发onAction事件

时间:2016-11-12 10:20:42

标签: javafx combobox actionevent


我有一个FXML编辑器和一个控制器,它在树视图中选择时设置域对象。因此,每次在树视图中选择新对象时,控制器都会解除编辑器中与前一个对象相关的所有控件,并绑定到新域对象的属性。这包括使用setItems在ComboBox中设置域对象的值。问题是setItems为项目列表中的每个项触发ComboBox的onAction事件处理程序。据我所知onAction应该定义当用户从ComboBox中选择一个条目而不是在加载ComboBox时触发的代码?!
我可以使用像鼠标释放事件或在setItems期间禁用actionevent的布尔信号量来解决这个问题。但是,由于我无法找到其他人要求这样做,我想知道更一般的事情是否有问题,我最好问社区。
我在我的OnAction事件处理程序中创建了一个Exception来打印stacktrace - 这有助于我理解上面解释的内容。也许这个堆栈跟踪可以帮助您了解发生了什么/错误。第一行是在FXML中链接到onActionEvent的方法,stacktrace中的最后一行是ComboBox的setItems调用:

at com.agiletunes.EditorCtrl.versionSelection(EditorCtrl.java:173)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.Trampoline.invoke(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769)
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    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.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:49)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Node.fireEvent(Node.java:8413)
    at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin.handleControlPropertyChanged(ComboBoxListViewSkin.java:179)
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase.lambda$registerChangeListener$61(BehaviorSkinBase.java:197)
    at com.sun.javafx.scene.control.MultiplePropertyChangeListenerHandler$1.changed(MultiplePropertyChangeListenerHandler.java:55)
    at javafx.beans.value.WeakChangeListener.changed(WeakChangeListener.java:89)
    at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:361)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105)
    at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
    at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
    at javafx.scene.control.ComboBoxBase.setValue(ComboBoxBase.java:150)
    at javafx.scene.control.ComboBox.updateValue(ComboBox.java:463)
    at javafx.scene.control.ComboBox.access$200(ComboBox.java:192)
    at javafx.scene.control.ComboBox$3.changed(ComboBox.java:446)
    at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:361)
    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.SelectionModel.setSelectedItem(SelectionModel.java:102)
    at javafx.scene.control.ComboBox$ComboBoxSelectionModel.lambda$new$154(ComboBox.java:494)
    at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:137)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.beans.property.ReadOnlyIntegerPropertyBase.fireValueChangedEvent(ReadOnlyIntegerPropertyBase.java:72)
    at javafx.beans.property.ReadOnlyIntegerWrapper.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:102)
    at javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)
    at javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:147)
    at javafx.scene.control.SelectionModel.setSelectedIndex(SelectionModel.java:68)
    at javafx.scene.control.SingleSelectionModel.updateSelectedIndex(SingleSelectionModel.java:215)
    at javafx.scene.control.SingleSelectionModel.clearSelection(SingleSelectionModel.java:68)
    at javafx.scene.control.SingleSelectionModel.select(SingleSelectionModel.java:144)
    at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin.lambda$createListView$323(ComboBoxListViewSkin.java:484)
    at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:349)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.beans.property.ReadOnlyIntegerPropertyBase.fireValueChangedEvent(ReadOnlyIntegerPropertyBase.java:72)
    at javafx.beans.property.ReadOnlyIntegerWrapper.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:102)
    at javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)
    at javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:147)
    at javafx.scene.control.SelectionModel.setSelectedIndex(SelectionModel.java:68)
    at javafx.scene.control.MultipleSelectionModelBase.clearSelection(MultipleSelectionModelBase.java:682)
    at javafx.scene.control.ListView$ListViewBitSetSelectionModel.updateDefaultSelection(ListView.java:1481)
    at javafx.scene.control.ListView$ListViewBitSetSelectionModel.updateItemsObserver(ListView.java:1459)
    at javafx.scene.control.ListView$ListViewBitSetSelectionModel.access$1200(ListView.java:1167)
    at javafx.scene.control.ListView$ListViewBitSetSelectionModel$1.invalidated(ListView.java:1197)
    at javafx.beans.WeakInvalidationListener.invalidated(WeakInvalidationListener.java:83)
    at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:349)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105)
    at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
    at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
    at javafx.scene.control.ListView.setItems(ListView.java:390)
    at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin.updateListViewItems(ComboBoxListViewSkin.java:222)
    at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin.lambda$new$322(ComboBoxListViewSkin.java:119)
    at javafx.beans.WeakInvalidationListener.invalidated(WeakInvalidationListener.java:83)
    at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:349)
    at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
    at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105)
    at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
    at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
    at javafx.scene.control.ComboBox.setItems(ComboBox.java:286)
    at com.agiletunes.EditorCtrl.setHierarchicalElement(EditorCtrl.java:120)

提前谢谢!

1 个答案:

答案 0 :(得分:3)

来自Javadoc of onAction

  

ComboBox操作,只要ComboBox value属性发生更改,就会调用此操作。这可能是由于value属性以编程方式更改[或...]

替换items会导致value被设置为null,这可能会导致onAction被触发。

您可以在替换onAction时删除items事件处理程序以防止它被触发,或者使用您的方法之一使用布尔值。

EventHandler<ActionEvent> handler = comboBox.getOnAction();
comboBox.setOnAction(null);
comboBox.setItems(FXCollections.observableArrayList("4", "5", "6"));
comboBox.setOnAction(handler);