I got a problem with an IndexOutOfBoundsException
while I want to update a ListView
in JavaFX.
What I need to do
I have a ListView
with elements that correspond to a small simulation. With a click on one list-element the graphical simulation updates based on the click a element of the ListView
. Afterwards the ListView
needs a update and other elements will be shown. That means all old elements will be removed and only the new ones will be shown.
My code looks like that:
public void init() {
// simCont.initSimulation() returns ArrayList
ObservableList<Default> obsDefaultList = FXCollections
.observableArrayList(simCont.initSimulation());
listTest.getItems().addAll(obsDefaultList);
listTest.getSelectionModel().selectedItemProperty()
.addListener(new ChangeListener<Default>() {
@Override
public void changed(
ObservableValue<? extends Default> observable,
Default oldValue, Default newValue) {
updateList(newValue);
}
});
}
private void updateList(Default chosen) {
ObservableList<Default> list = FXCollections
.observableArrayList(simCont.doSimulationStep(chosen.getId()));
listTest.getItems().clear();
listTest.getItems().addAll(list);
}
At first there are two elements shown. When I click on one of them the ListView
updates but I get an IndexOutOfBoundsException
.
Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException
at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.subList(ReadOnlyUnbackedObservableList.java:136)
at javafx.collections.ListChangeListener$Change.getAddedSubList(ListChangeListener.java:242)
at com.sun.javafx.scene.control.behavior.ListViewBehavior.lambda$new$174(ListViewBehavior.java:258)
at com.sun.javafx.scene.control.behavior.ListViewBehavior$$Lambda$145/442103778.onChanged(Unknown Source)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.callObservers(ReadOnlyUnbackedObservableList.java:75)
at javafx.scene.control.MultipleSelectionModelBase.clearAndSelect(MultipleSelectionModelBase.java:331)
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.simpleSelect(CellBehaviorBase.java:242)
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.doSelect(CellBehaviorBase.java:206)
at com.sun.javafx.scene.control.behavior.CellBehaviorBase.mousePressed(CellBehaviorBase.java:132)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:95)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
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:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3724)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3452)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1728)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2461)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:348)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:273)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:382)
at com.sun.glass.ui.View.handleMouseEvent(View.java:553)
at com.sun.glass.ui.View.notifyMouse(View.java:925)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at de.hhn.unitylab.controller.SimulationController.doSimulationStep(SimulationController.java:65)
at de.hhn.unitylab.ui.SimulatorViewController.updateList(SimulatorViewController.java:107)
at de.hhn.unitylab.ui.SimulatorViewController.access$0(SimulatorViewController.java:105)
at de.hhn.unitylab.ui.SimulatorViewController$1.changed(SimulatorViewController.java:94)
at de.hhn.unitylab.ui.SimulatorViewController$1.changed(SimulatorViewController.java:1)
at com.sun.javafx.binding.ExpressionHelper$SingleChange.fireValueChangedEvent(ExpressionHelper.java:182)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ReadOnlyObjectWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyObjectWrapper.java:176)
at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:142)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:145)
at javafx.scene.control.SelectionModel.setSelectedItem(SelectionModel.java:102)
at javafx.scene.control.MultipleSelectionModelBase.lambda$new$34(MultipleSelectionModelBase.java:67)
at javafx.scene.control.MultipleSelectionModelBase$$Lambda$127/2138925075.invalidated(Unknown Source)
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.ReadOnlyIntegerWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:176)
at javafx.beans.property.ReadOnlyIntegerWrapper.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:142)
at javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)
at javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:146)
at javafx.scene.control.SelectionModel.setSelectedIndex(SelectionModel.java:68)
at javafx.scene.control.MultipleSelectionModelBase.select(MultipleSelectionModelBase.java:357)
at javafx.scene.control.ListView.lambda$new$156(ListView.java:374)
at javafx.scene.control.ListView$$Lambda$126/1092624378.invalidated(Unknown Source)
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.ReadOnlyBooleanPropertyBase.fireValueChangedEvent(ReadOnlyBooleanPropertyBase.java:72)
at javafx.scene.Node$FocusedProperty.notifyListeners(Node.java:7526)
at javafx.scene.Scene$13.invalidated(Scene.java:2046)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:111)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:145)
at javafx.scene.Scene$KeyHandler.setFocusOwner(Scene.java:3891)
at javafx.scene.Scene$KeyHandler.requestFocus(Scene.java:3938)
at javafx.scene.Scene$KeyHandler.access$1900(Scene.java:3877)
at javafx.scene.Scene.requestFocus(Scene.java:2010)
at javafx.scene.Node.requestFocus(Node.java:7687)
at com.sun.javafx.scene.control.behavior.ListViewBehavior.mousePressed(ListViewBehavior.java:360)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:95)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
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.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3724)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3452)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1728)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2461)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:348)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:273)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:382)
at com.sun.glass.ui.View.handleMouseEvent(View.java:553)
at com.sun.glass.ui.View.notifyMouse(View.java:925)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
Debugging was confusing because I found no reason for the exception. I searched the web but found nothing that worked for me. Hopefully somebody can help me with that issue.
Bit late, but since you are still getting the exceptions, here's my two cents. I was getting the same error and here's what worked for me.
You can't update UI elements from a non-main thread. One way to do this is make a Runnable and schedule it on the main thread by runLater.
Platform.runLater(new Runnable() {
@Override public void run() {
//put your code here
}});
Put the observalble list outside of a method (just like a normal field)
ObservableList<Default> listData = FXCollections.observableArrayList()
public void initialize(Url url, ResourceBundle rb) {
listData.addAll(myService.getFoo);
listTest.setItems(listData);
//You could use lambdas here if you use Java8
listTest.getSelectionModel.selectedItemProperty()
.addListener(new ChangeListener<Default>(){
@Override
public void changed(ObservableValue<? extends Default> observable,
Default oldValue, Default newValue) {
//Update the graphical simulations somewhere here
listData.clear();
listData.add(new Default(..)); //Add new values to list
}
});
}
If you bind the list to a observable list objects, the table changes whenever the observable list (here listData
). What you did wrong create a new observable list every time.
I had exactly the same problem while using a ComboBox
and trying to update the backing observablelist
.
I fixed it by changing the ComboBox
to a ChoiceBox
and now I don't get the IndexOutOfBoundsException
anymore.
Did you try using other containers?
I think you are in the similar situation of this answer:JavaFX ComboBox change value causes IndexOutOfBoundsException
try
Platform.runLater(() -> updateList(newValue) )
instead of updateList(newValue)
In my case this issue occured when I had ScenicView opened beside my JavaFX application. Closing it solved the problem.
来源:https://stackoverflow.com/questions/26343495/indexoutofboundsexception-while-updating-a-listview-in-javafx