gpt4 book ai didi

java - 使带有复选框的 ListView 与字符串列表保持同步

转载 作者:行者123 更新时间:2023-12-02 02:49:51 24 4
gpt4 key购买 nike

我想创建一个简单的 ListView 并将其所选项目与列表中包含的字符串同步。我发现我可以使用 setCellFactory() 方法,当选择/取消选择项目时我更新字符串列表,但我不知道如何做相反的事情,当字符串列表更改时更新 ListView 项目选择。

到目前为止我已经:

ListView<String> selectedAttributes = new ListView<>();
String[] toppings = {"Cheese", "Pepperoni", "Black Olives"};
listViewAttributes.getItems().addAll(toppings);
listViewAttributes.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) {
selectedAttributes.add(item);
} else {
selectedAttributes.remove(item);
}
System.out.println(selectedAttributes.size());

});
return observable;
}
}));

这使得列表selectedAttributes元素在选中/取消选中ListView项目时更新,现在我想在列表内容更改时更新ListView项目选择。

我怎样才能做到这一点?

最佳答案

假设selectedAttributes是一个ObservableSet,(或者一个ObservableList,您仔细检查没有多次添加相同的项目)添加

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);
}
}
<小时/>

您做事的方式(用一个单独的列表代表所选项目)变得有点复杂。此时,为列表中具有 observable 属性的项目定义适当的模型类可能会更容易:

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:

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);
}
}

关于java - 使带有复选框的 ListView 与字符串列表保持同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44022381/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com