2016-11-12 71 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