2016-11-12 4 views
2


J'ai un éditeur en FXML et un contrôleur qui définit l'objet domaine lors de la sélection dans une vue arborescente. Ainsi, chaque fois qu'un nouvel objet est sélectionné dans l'arborescence, le contrôleur dissocie tous les contrôles dans l'éditeur de l'objet précédent et se lie aux propriétés du nouvel objet de domaine. Cela inclut la définition de valeurs à partir de l'objet domaine dans un contrôle ComboBox à l'aide de setItems. Le problème est que setItems déclenche le gestionnaire d'événement onAction du ComboBox pour chaque élément de la liste d'éléments. À mon avis onAction devrait définir le code déclenché lorsque l'utilisateur sélectionne une entrée de la ComboBox et non lorsque le ComboBox est chargé ?!
Je pourrais résoudre ce problème en utilisant quelque chose comme un événement de lancement de souris ou un sémaphore booléen qui désactive l'actionevent pendant setItems. Cependant, comme je ne pouvais pas trouver quelqu'un d'autre pour demander cela, je me demande si quelque chose ne va pas en général et je ferais mieux de demander à la communauté.
J'ai créé une exception dans mon gestionnaire d'événement OnAction pour imprimer la pile, ce qui m'a aidé à comprendre ce que j'ai expliqué ci-dessus. Peut-être que ce stacktrace vous aide à comprendre ce qui se passe/mal. La première ligne est la méthode qui est liée au FXML à la onActionEvent et la dernière ligne du stacktrace est l'appel setItems du ComboBox:JavaFX ComboBox setItems déclenche l'événement 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) 

Merci à l'avance!

Répondre

3

De l'Javadoc of onAction

L'action ComboBox, qui est invoqué chaque fois que le ComboBoxvalue propriété est modifiée. Cela peut être dû à la propriété value être modifié par programmation [ou ...]

Remplacement du items conduit à l'value étant mis à null qui peut conduire à onAction être déclenché.

Vous pouvez simplement supprimer le gestionnaire d'événements onAction lorsque vous remplacez le items pour l'empêcher d'être déclenché ou utilisez l'une de vos approches avec le booléen.

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

Vous avez raison. Bon point. Je vous remercie! – Alex

+0

@fabian Connaissez-vous un autre événement appelé uniquement lorsque la valeur est modifiée à partir de l'interface, et non par programmation? Ou comment je pourrais différencier les deux cas? – Laura