2016-11-12 9 views
2


Ich habe einen Editor in FXML und einen Controller, der das Domänenobjekt bei der Auswahl in einer Strukturansicht setzt. Jedes Mal, wenn in der Strukturansicht ein neues Objekt ausgewählt wird, löst der Controller alle Steuerelemente im Editor vom vorherigen Objekt und bindet sich an die Eigenschaften des neuen Domänenobjekts. Dazu gehört das Festlegen von Werten aus dem Domänenobjekt in einer ComboBox mithilfe von setItems. Das Problem ist, dass setItems den Ereignishandler onAction der ComboBox für jedes Element in der Elementliste auslöst. Zu meinem Verständnis sollte onAction den Code definieren, der ausgelöst wird, wenn der Benutzer einen Eintrag aus der ComboBox auswählt und nicht, wenn die ComboBox geladen wird ?!
Ich könnte dieses Problem beheben, indem ich entweder ein Maus-Release-Ereignis oder ein boolesches Semaphor verwende, das das actionevent während setItems deaktiviert. Da ich jedoch niemanden finden konnte, der danach fragte, frage ich mich, ob irgendetwas im Allgemeinen nicht stimmt und ich bitte besser die Community.
Ich habe eine Exception in meinem OnAction Event Handler erstellt, um den StackTrace zu drucken - was mir geholfen hat zu verstehen, was ich oben erklärt habe. Vielleicht hilft dir dieser Stacktrace zu verstehen, was vor sich geht/was falsch ist. Die erste Zeile ist die Methode, die in der FXML zum onActionEvent und die letzten Zeile in der Stacktrace verbunden ist, ist der setItems Aufruf des ComboBox:JavaFX ComboBox setItems löst OnAction-Ereignis

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) 

Vielen Dank im Voraus!

Antwort

3

Vom Javadoc of onAction

Die ComboBox Aktion, die aufgerufen wird, wenn die ComboBoxvalue Eigenschaft geändert wird. Dies kann darauf zurückzuführen sein, die value Eigenschaft programmatisch geändert werden [oder ...]

Austausch der items führt zum value zu null gesetzt werden, die zu onAction wird ausgelöst führen kann.

Sie können einfach den onAction Event-Handler entfernen, wenn Sie die items ersetzen, um zu verhindern, dass es ausgelöst wird, oder verwenden Sie einen Ihrer Ansatz mit dem boolean.

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

Sie haben Recht. Guter Punkt. Vielen Dank! – Alex

+0

@fabian Kennen Sie ein anderes Ereignis, das nur aufgerufen wird, wenn der Wert von der Schnittstelle geändert wird, nicht programmatisch? Oder wie könnte ich zwischen den beiden Fällen unterscheiden? – Laura

Verwandte Themen