Java 使带有复选框的ListView与字符串列表保持同步
我想创建一个简单的ListView,并将其所选项目与列表中包含的字符串同步。我发现我可以使用setCellFactory()方法,在选择/取消选择项目时更新字符串列表,但我不知道如何做相反的事情,在字符串列表更改时更新ListView项目选择 到目前为止,我已经:Java 使带有复选框的ListView与字符串列表保持同步,java,listview,checkbox,javafx,Java,Listview,Checkbox,Javafx,我想创建一个简单的ListView,并将其所选项目与列表中包含的字符串同步。我发现我可以使用setCellFactory()方法,在选择/取消选择项目时更新字符串列表,但我不知道如何做相反的事情,在字符串列表更改时更新ListView项目选择 到目前为止,我已经: ListView<String> selectedAttributes = new ListView<>(); String[] toppings = {"Cheese", "Pepperoni", "Blac
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;
}
}));
ListView SelectedAttribute=new ListView();
String[]浇头={“奶酪”、“辣香肠”、“黑橄榄”};
listViewAttributes.getItems().addAll(浇头);
setCellFactory(CheckBoxListCell.forListView(新回调)(){
@凌驾
公共observeValue调用(字符串项){
BooleanProperty observable=新的SimpleBoleanProperty();
observable.addListener((obs、wasSelected、isNowSelected)->{
如果(现在已选定){
选择属性。添加(项);
}否则{
所选属性。删除(项);
}
System.out.println(selectedAttributes.size());
});
可观测收益;
}
}));
这使得列表selectedAttributes
元素在选中/取消选中ListView项时更新,现在我想在列表内容更改时更新ListView项选择
我该怎么做 假设
selectedAttributes
是一个observedset
,(或者是一个observedsist
,在该列表中,您仔细检查后,不会多次添加同一项)添加
那么剩下的代码就容易多了:
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));
以下是采用这种方法的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);
}
}
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.util.array;
导入java.util.List;
导入javafx.application.application;
导入javafx.beans.property.BooleanProperty;
导入javafx.beans.property.SimpleBoleAnProperty;
导入javafx.geometry.Insets;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.ListView;
导入javafx.scene.control.cell.CheckBoxListCell;
导入javafx.scene.layout.BorderPane;
导入javafx.stage.stage;
带有复选框的公共类ListView扩展了应用程序{
@凌驾
公共无效开始(阶段primaryStage){
ListView ToppingList=新建ListView();
顶部奶酪=新的顶部(“奶酪”);
浇头番茄酱=新浇头(“番茄酱”);
浇头辣香肠=新浇头(“辣香肠”);
浇头黑橄榄=新浇头(“黑橄榄”);
getItems().addAll(奶酪、番茄酱、意大利辣香肠、黑橄榄);
setCellFactory(CheckBoxListCell.forListView(Topping::selectedProperty));
//更改列表中所选内容的按钮示例
//这将选择“奶酪”和“番茄酱”,并取消选择其他所有内容
Button justCheese=新按钮(“只是一个奶酪比萨饼”);
List cheesepizzaatoppings=Arrays.asList(cheese,tomsause);
justCheese.setOnAction(e->ToppingList.getItems().forEach(
topping->topping.setSelected(cheesePizzaToppings.contains(topping));
BorderPane根=新的BorderPane(TopingList);
根.立顶(justCheese);
边框窗格。设置边框(justCheese,新插图(5));
场景=新场景(根);
初级阶段。场景(场景);
primaryStage.show();
}
公共静态类顶级{
私有最终字符串名;
选定的私有最终布尔属性=新SimpleBoleAnProperty();
公共顶部(字符串名称){
this.name=名称;
}
公共布尔属性selectedProperty(){
返回选中的;
}
公共最终选举(){
返回selectedProperty().get();
}
公共最终无效设置已选定(布尔值已选定){
selectedProperty().set(已选择);
}
公共字符串getName(){
返回名称;
}
@凌驾
公共字符串toString(){
返回getName();
}
}
公共静态void main(字符串[]args){
发射(args);
}
}
假设selectedAttributes
是一个observateSet
,(或者是一个observateSist
,在这里您仔细检查并没有多次添加同一项)添加
那么剩下的代码就容易多了:
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));
以下是采用这种方法的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);
}
}
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.util.array;
导入java.util.List;
导入javafx.application.application;
导入javafx.beans.property.BooleanProperty;
导入javafx.beans.property.SimpleBoleAnProperty;
导入javafx.geometry.Insets;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.ListView;
导入javafx.scene.control.cell.CheckBoxListCell;
导入javafx.scene.layout.BorderPane;
导入javafx.stage.stage;
带有复选框的公共类ListView扩展了应用程序{
@凌驾
公共无效开始(阶段primaryStage){
ListView ToppingList=新建ListView();
顶部奶酪=新的顶部(“奶酪”);
浇头番茄酱=新浇头(“番茄酱”);
浇头辣香肠=新浇头(“辣香肠”);
浇头黑橄榄=新浇头(“黑橄榄”);
getItems().addAll(奶酪、番茄酱、意大利辣香肠、黑橄榄);
setCellFactory(CheckBoxListCell.forListView(Topping::selectedProperty));
//更改列表中所选内容的按钮示例
//这将选择“奶酪”和“番茄酱”,并取消选择其他所有内容
Button justCheese=新按钮(“只是一个奶酪比萨饼”);
List cheesepizzaatoppings=Arrays.asList(cheese,tomsause);
justCheese.setOnAction(e->ToppingList.getItems().forEach(
topping->topping.setSelected(cheesePizzaToppings.contains(topping));
ListView<String> listViewAttributes = new ListView<>();
List<String> selectedAttributes = new ArrayList<>();
selectedAttributes.add("Pepperoni");
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();
for (int i = 0; i < selectedAttributes.size(); i++) {
if (item.equals(selectedAttributes.get(i))) {
observable.set(true);
}
}
observable.addListener((obs, wasSelected, isNowSelected) -> {
if (isNowSelected) {
selectedAttributes.add(item);
} else {
selectedAttributes.remove(item);
}
System.out.println(selectedAttributes.size());
});
return observable;
}
}));