Hi,
I want to synchronize a List<String> with the selected items of a ListView. In the real project, I want to synchronize the selected items of a TreeView and the selected images of a galery (custom control).
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TestBindingsList extends Application {
@Override
public void start(Stage stage) throws Exception {
System.out.println(System.getProperty("java.version"));
List<String> items = Arrays.asList("One", "Two", "Three");
ListView<String> listView = new ListView<String>(FXCollections.observableArrayList(items));
listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
listView.getSelectionModel().getSelectedItems().addListener(new ListChangeListener<String>() {
@Override
public void onChanged(Change<? extends String> c) {
System.out.println(c);
}
});
List<String> list = new ArrayList<String>();
Bindings.bindContent(list, listView.getSelectionModel().getSelectedItems());
Button btnTest = new Button("Test");
btnTest.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent e) {
System.out.println(list);
}
});
VBox vBox = new VBox(8);
Scene scene = new Scene(vBox);
vBox.getChildren().addAll(listView, btnTest);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
In most cases, the program works as expected but sometimes there are some issues.
- For example, when I launch the application and select all the items with Ctrl-A, the event { [One, Two, Three] added at 0, } is fired so the list of strings contains incorrectly 4 elements [One, Two, Three, One].
- Another example, when selecting all the items (with Shift+End), two events are fired { [One] removed at 0, } and { [One, Two, Three] added at 0, }, that's correct. But when I remove the last element with Shift-Up, 3 events are fired { [Two] removed at 1, }, { [Three] removed at 2, } and { [Two] added at 1, } and an exception is thrown:
java.lang.IndexOutOfBoundsException: toIndex = 3
at java.util.ArrayList.subListRangeCheck(ArrayList.java:1004)
at java.util.ArrayList.subList(ArrayList.java:996)
at com.sun.javafx.binding.ContentBinding$ListContentBinding.onChanged(ContentBinding.java:111)
Any ideas?