-
Bug
-
Resolution: Fixed
-
P3
-
8
The list "selectedCellsSeq" tries to map the SelectedCellsMap class to the (Observable)List interface but breaks the List contract.
If you call subList(-1, 0) a List of size 1 is returned with a single null-value. This happens, since the get-call is forwarded to the SelectedCellsMap get method, which just returns null if the index is below zero.
This is a violation of the API that states "Throws: IndexOutOfBoundsException - if the index is out of range (index < 0 || index > size())" for both, subList and get-methods.
The following code is a copy of what the TableViewArrayListSelectionModel does, to demonstrate the problem:
public class Test {
public static void main(String[] args) {
final SelectedCellsMap<TablePosition> selectedCellsMap = new SelectedCellsMap<>(
new ListChangeListener<TablePosition>() {
@Override
public void onChanged(javafx.collections.ListChangeListener.Change<? extends TablePosition> c) {
// Do nothing
}
});
ReadOnlyUnbackedObservableList<TablePosition<Object, ?>> selectedCellsSeq = new ReadOnlyUnbackedObservableList<TablePosition<Object, ?>>() {
@Override
public TablePosition<Object, ?> get(int i) {
return selectedCellsMap.get(i);
}
@Override
public int size() {
return selectedCellsMap.size();
}
};
// Lets do something really nonsense but this happens due to another bug
List<TablePosition<Object, ?>> subList = selectedCellsSeq.subList(-1, 0);
//Whoops, a list of size 1 as a sublist of an empty list:
System.out.println(subList.size() + " " + subList);
}
}
This bug hides another bug, that I'm currently hunting for. (Tested with JDK 8 b127)
If you call subList(-1, 0) a List of size 1 is returned with a single null-value. This happens, since the get-call is forwarded to the SelectedCellsMap get method, which just returns null if the index is below zero.
This is a violation of the API that states "Throws: IndexOutOfBoundsException - if the index is out of range (index < 0 || index > size())" for both, subList and get-methods.
The following code is a copy of what the TableViewArrayListSelectionModel does, to demonstrate the problem:
public class Test {
public static void main(String[] args) {
final SelectedCellsMap<TablePosition> selectedCellsMap = new SelectedCellsMap<>(
new ListChangeListener<TablePosition>() {
@Override
public void onChanged(javafx.collections.ListChangeListener.Change<? extends TablePosition> c) {
// Do nothing
}
});
ReadOnlyUnbackedObservableList<TablePosition<Object, ?>> selectedCellsSeq = new ReadOnlyUnbackedObservableList<TablePosition<Object, ?>>() {
@Override
public TablePosition<Object, ?> get(int i) {
return selectedCellsMap.get(i);
}
@Override
public int size() {
return selectedCellsMap.size();
}
};
// Lets do something really nonsense but this happens due to another bug
List<TablePosition<Object, ?>> subList = selectedCellsSeq.subList(-1, 0);
//Whoops, a list of size 1 as a sublist of an empty list:
System.out.println(subList.size() + " " + subList);
}
}
This bug hides another bug, that I'm currently hunting for. (Tested with JDK 8 b127)