Hallo Forum,
ich habe von GitHub eine CheckBoxListCellDemo geladen und versuche diese zu analysieren. Dabei ist mir aufgefallen, dass beim Mausklick in den Textteil der Callback zweimal aufgerufen wird und einmal das Element der bisherigen Selektion und einmal das neu geklickte Element zeigt. Allerdings hängt die Reihenfolge davon ab ob die neue Selektion vor oder nach der bisherigen Selektion ist. Dadurch ist eine eindeutige Identifikation nicht möglich.
Der Callback befindet sich nach der Kommentarzeile mit den XXXXXXX
ich habe von GitHub eine CheckBoxListCellDemo geladen und versuche diese zu analysieren. Dabei ist mir aufgefallen, dass beim Mausklick in den Textteil der Callback zweimal aufgerufen wird und einmal das Element der bisherigen Selektion und einmal das neu geklickte Element zeigt. Allerdings hängt die Reihenfolge davon ab ob die neue Selektion vor oder nach der bisherigen Selektion ist. Dadurch ist eine eindeutige Identifikation nicht möglich.
Der Callback befindet sich nach der Kommentarzeile mit den XXXXXXX
Code:
public class App extends Application {
public static void main(String[] args) {
launch(args);
}
CheckBox cb = new CheckBox();
// CheckBox cb = CheckBoxBuilder.create().build();
final ObservableList<Employee> data = FXCollections.observableArrayList();
ChangeListener<Boolean> listener = new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> paramObservableValue, Boolean paramT1, Boolean selected) {
if (selected) {
boolean flag = true;
for (Employee emp : data) {
if (!emp.getSelected()) {
flag = false;
break;
}
}
if (flag) {
cb.setSelected(true);
}
} else {
cb.setSelected(false);
}
}
};
@Override
public void start(Stage primaryStage) {
// alle Elemente selektieren / deselektieren
cb.selectedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> paramObservableValue, Boolean paramT1, Boolean paramT2) {
for (Employee emp : data) {
emp.setSelected(paramT2);
}
}
});
//END Listener -----------------------------------
primaryStage.setTitle("CheckBoxListCell Sample");
for (int i = 0; i < 5; i++) {
data.add(new Employee(i % 2 == 0 ? true : false, "Empl " + i));
}
final ListView<Employee> listView = new ListView<>();
listView.setPrefSize(200, 250);
listView.setEditable(false);
// Listener zu jeden Element hinzufügen
for (Employee employee : data) {
employee.selectedProperty().addListener(listener);
}
// Daten nach ListView
listView.setItems(data);
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// Wird beim Erstellen der ListView für jedes Element aufgerufen
// und bei jeden Click auf den Textteil der Liste
Callback<Employee, ObservableValue<Boolean>> getProperty = new Callback<Employee, ObservableValue<Boolean>>() {
@Override
public BooleanProperty call(Employee layer) {
System.out.println("Text selektiert: " + layer.getName());
return layer.selectedProperty();
}
};
//END Callback ---------------------------------------
// Nur bei Erstellen
// Erstellt CellFactory (Checkboxen)
Callback<ListView<Employee>, ListCell<Employee>> forListView = CheckBoxListCell.forListView(getProperty);
listView.setCellFactory(forListView);
StackPane root = new StackPane();
Button btn = new Button("Show");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent paramT) {
for (Employee employee : data) {
System.out.println(employee.getSelected());
}
}
});
VBox vb = new VBox();
vb.getChildren().addAll(listView, btn, cb);
root.getChildren().add(vb);
primaryStage.setScene(new Scene(root, 200, 250));
primaryStage.show();
}
class Employee {
private final SimpleBooleanProperty selected;
private final SimpleStringProperty name;
public Employee(boolean id, String name) {
this.selected = new SimpleBooleanProperty(id);
this.name = new SimpleStringProperty(name);
}
public boolean getSelected() {
return selected.get();
}
public void setSelected(boolean selected) {
this.selected.set(selected);
}
public String getName() {
return name.get();
}
public void setName(String fName) {
name.set(fName);
}
public SimpleBooleanProperty selectedProperty() {
return selected;
}
@Override
public String toString() {
return getName();
}
}
}