2016-11-12 72 views
2


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

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) 

预先感谢您!

回答

3

Javadoc of onAction

ComboBox动作,每当ComboBoxvalue属性被改变时调用。到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); 
+0

你说得对。好点子。谢谢! – Alex

+0

@fabian您是否知道另一个仅在从接口更改值时才调用的事件,而不是以编程方式进行调用?或者我如何区分这两种情况? – Laura