はここ
observable.set(selectedAttributes.contains(item));
selectedAttributes.addListener((ListChangeListener.Change<? extends String> c) ->
observable.set(selectedAttributes.contains(item)));
を追加し、このアプローチでSSCCEです:
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableSet;
import javafx.collections.SetChangeListener;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.CheckBoxListCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class ListViewWithCheckBoxes extends Application {
@Override
public void start(Stage primaryStage) {
ListView<String> toppingsList = new ListView<>();
String[] toppings = {"Cheese", "Tomato Sauce", "Pepperoni", "Black Olives"};
toppingsList.getItems().addAll(toppings);
ObservableSet<String> selectedToppings = FXCollections.observableSet();
toppingsList.setCellFactory(CheckBoxListCell.forListView(new Callback<String, ObservableValue<Boolean>>() {
@Override
public ObservableValue<Boolean> call(String item) {
BooleanProperty observable = new SimpleBooleanProperty();
observable.addListener((obs, wasSelected, isNowSelected) -> {
if (isNowSelected) {
selectedToppings.add(item);
} else {
selectedToppings.remove(item);
}
System.out.println(selectedToppings.size());
});
observable.set(selectedToppings.contains(item));
selectedToppings.addListener((SetChangeListener.Change<? extends String> c) ->
observable.set(selectedToppings.contains(item)));
return observable;
}
}));
// example of a button that changes what's selected in the list
// This selects "Cheese" and "Tomato Sauce" and deselects everything else
Button justCheese = new Button("Just a cheese pizza");
justCheese.setOnAction(e -> {
selectedToppings.clear();
selectedToppings.add("Cheese");
selectedToppings.add("Tomato Sauce");
});
BorderPane root = new BorderPane(toppingsList);
root.setTop(justCheese);
BorderPane.setMargin(justCheese, new Insets(5));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
あなたがしていること(選択されたアイテムを表す別のリスト)は、ちょっと複雑になります。この時点で、それだけで観察可能な性質を持っているリスト内の項目のための適切なモデルクラスを定義する方が簡単でしょう:
public class Topping {
private final String name ;
private final BooleanProperty selected = new SimpleBooleanProperty();
public Topping(String name) {
this.name = name ;
}
public BooleanProperty selectedProperty() {
return selected ;
}
public final boolean isSelected() {
return selectedProperty().get();
}
public final void setSelected(boolean selected) {
selectedProperty().set(selected);
}
public String getName() {
return name ;
}
@Override
public String toString() {
return getName();
}
}
その後、残りのコードは、はるかに簡単です:
ListView<Topping> listView = new ListView<>();
List<Topping> toppings = Arrays.asList(
new Topping("Cheese"),
new Topping("Pepperoni") ,
new Topping("Black Olives"));
listView.getItems().addAll(toppings);
listView.setCellFactory(CheckBoxListCell.forListView(Topping::selectedProperty));
そして今、あなたはUIのチェックボックスの外に項目を選択することができます。ここ
for (Topping topping : toppings) {
topping.setSelected(true);
}
このアプローチにSSCCEある:
のequals()メソッドによって、リストに文字列の項目を比較するためにループに使用して
import java.util.Arrays;
import java.util.List;
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.cell.CheckBoxListCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class ListViewWithCheckBoxes extends Application {
@Override
public void start(Stage primaryStage) {
ListView<Topping> toppingsList = new ListView<>();
Topping cheese = new Topping("Cheese");
Topping tomSauce = new Topping("Tomato Sauce");
Topping pepperoni = new Topping("Pepperoni");
Topping blackOlives = new Topping("Black Olives");
toppingsList.getItems().addAll(cheese, tomSauce, pepperoni, blackOlives);
toppingsList.setCellFactory(CheckBoxListCell.forListView(Topping::selectedProperty));
// example of a button that changes what's selected in the list
// This selects "Cheese" and "Tomato Sauce" and deselects everything else
Button justCheese = new Button("Just a cheese pizza");
List<Topping> cheesePizzaToppings = Arrays.asList(cheese, tomSauce);
justCheese.setOnAction(e -> toppingsList.getItems().forEach(
topping -> topping.setSelected(cheesePizzaToppings.contains(topping))));
BorderPane root = new BorderPane(toppingsList);
root.setTop(justCheese);
BorderPane.setMargin(justCheese, new Insets(5));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
public static class Topping {
private final String name ;
private final BooleanProperty selected = new SimpleBooleanProperty();
public Topping(String name) {
this.name = name ;
}
public BooleanProperty selectedProperty() {
return selected ;
}
public final boolean isSelected() {
return selectedProperty().get();
}
public final void setSelected(boolean selected) {
selectedProperty().set(selected);
}
public String getName() {
return name ;
}
@Override
public String toString() {
return getName();
}
}
public static void main(String[] args) {
launch(args);
}
}