I want to enable validations for my combobox to restrict access to some values. I could just remove these inaccessible items from the list, yes, but I would like the user to see other options, even if he cannot select them (yet).
Problem: choosing a different value in the change list throws an IndexOutOfBoundsException, and I have no idea why.
Here is the SSCCE. It creates a ComboBox with integer values, and the first one is selected by default. Then I tried to save it very simply: every change in the value is considered โwrongโ, and I change the selection to the first element. But still, IndexOutOfBounds:
import javafx.application.Application; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.control.ComboBox; import javafx.stage.Stage; public class Tester extends Application{ public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) throws Exception { ComboBox<Integer> box = new ComboBox<Integer>(); ObservableList<Integer> vals= FXCollections.observableArrayList(0,1,2,3); box.setItems(vals); box.getSelectionModel().select(0); box.getSelectionModel().selectedIndexProperty().addListener((observable,oldValue,newValue)->{ System.out.println(oldValue+","+newValue); box.getSelectionModel().select(0); }); Scene scene = new Scene(new Group(box),500,500); stage.setScene(scene); stage.show(); } }
I tested it with valueProperty, selectedItemProperty and selectedIndexProperty, as well as all of them:
box.getSelectionModel().select(0); box.getSelectionModel().selectFirst(); box.getSelectionModel().selectPrevious(); box.setValue(0); if (oldValue.intValue() < newValue.intValue()) box.getSelectionModel().select(oldValue.intValue());
The only thing that works is setting the value itself:
box.getSelectionModel().select(box.getSelectionModel().getSelectedIndex()); box.setValue(box.getValue));
Here is the exception:
Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.subList(Unknown Source) at javafx.collections.ListChangeListener$Change.getAddedSubList(Unknown Source) at com.sun.javafx.scene.control.behavior.ListViewBehavior.lambda$new$178(Unknown Source) at com.sun.javafx.scene.control.behavior.ListViewBehavior$$Lambda$126/644961012.onChanged(Unknown Source) at javafx.collections.WeakListChangeListener.onChanged(Unknown Source) at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(Unknown Source) at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(Unknown Source) at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.callObservers(Unknown Source) at javafx.scene.control.MultipleSelectionModelBase.clearAndSelect(Unknown Source) at javafx.scene.control.ListView$ListViewBitSetSelectionModel.clearAndSelect(Unknown Source) at com.sun.javafx.scene.control.behavior.CellBehaviorBase.simpleSelect(Unknown Source) at com.sun.javafx.scene.control.behavior.CellBehaviorBase.doSelect(Unknown Source) at com.sun.javafx.scene.control.behavior.CellBehaviorBase.mousePressed(Unknown Source) at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source) at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source) at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source) at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source) at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source) at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source) at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source) at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source) at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source) at javafx.event.Event.fireEvent(Unknown Source) at javafx.scene.Scene$MouseHandler.process(Unknown Source) at javafx.scene.Scene$MouseHandler.access$1500(Unknown Source) at javafx.scene.Scene.impl_processMouseEvent(Unknown Source) at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source) at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$350(Unknown Source) at com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$172/2037973250.get(Unknown Source) at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(Unknown Source) at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source) at com.sun.glass.ui.View.handleMouseEvent(Unknown Source) at com.sun.glass.ui.View.notifyMouse(Unknown Source) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.lambda$null$145(Unknown Source) at com.sun.glass.ui.win.WinApplication$$Lambda$36/2117255219.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
What am I doing wrong?