Java 如何在单元工厂中以编程方式选择组合框值?
MyJava 如何在单元工厂中以编程方式选择组合框值?,java,javafx,Java,Javafx,MyTableView使用自定义的CellFactory在一列中显示一个组合框,允许用户从可用选项中进行选择。这些选项在填充TableView后加载(因为它们可以根据用户在场景中其他位置的选择进行更改) 在下面的MCVE中,我的项目类有两列:名称和颜色。在Color列中,我有组合框,它将显示项目的itemColor属性的当前值 您将看到,组合框尚未填充值列表,并且项“三”没有选择值 我需要的是: 当用户单击“加载可用颜色”按钮时,将创建组合框的列表。用户现在可以选择任何可用的颜色。但是,如果项目
TableView
使用自定义的CellFactory
在一列中显示一个组合框,允许用户从可用选项中进行选择。这些选项在填充TableView
后加载(因为它们可以根据用户在场景中其他位置的选择进行更改)
在下面的MCVE中,我的项目
类有两列:名称
和颜色
。在Color
列中,我有组合框
,它将显示项目的itemColor
属性的当前值
您将看到,组合框
尚未填充值列表,并且项“三”没有选择值
我需要的是:
当用户单击“加载可用颜色”按钮时,将创建组合框的列表。用户现在可以选择任何可用的颜色。但是,如果项目的颜色还没有值,我希望自动选择组合框
中的第一种颜色;因此,项目“三”现在将显示颜色“红色”被选中
MCVE
Item.java:
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Item {
private StringProperty itemName = new SimpleStringProperty();
private StringProperty itemColor = new SimpleStringProperty();
public Item(String name, String color) {
this.itemName.set(name);
this.itemColor.set(color);
}
public String getItemName() {
return itemName.get();
}
public void setItemName(String itemName) {
this.itemName.set(itemName);
}
public StringProperty itemNameProperty() {
return itemName;
}
public String getItemColor() {
return itemColor.get();
}
public void setItemColor(String itemColor) {
this.itemColor.set(itemColor);
}
public StringProperty itemColorProperty() {
return itemColor;
}
}
import javafx.application.Application;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
// List of items
private static ObservableList<Item> listOfItems = FXCollections.observableArrayList();
// List of available Colors. These will be selectable from the ComboBox
private static ObservableList<String> availableColors = FXCollections.observableArrayList();
public static void main(String[] args) {
launch(args);
}
private static void buildSampleData() {
availableColors.addAll("Red", "Blue", "Green", "Yellow", "Black");
}
@Override
public void start(Stage primaryStage) {
// Simple Interface
VBox root = new VBox(10);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(10));
// Build a list of sample data. This data is loaded from my data model and passed to the constructor
// of this editor in my real application.
listOfItems.addAll(
new Item("One", "Black"),
new Item("Two", "Black"),
new Item("Three", null),
new Item("Four", "Green"),
new Item("Five", "Red")
);
// TableView to display the list of items
TableView<Item> tableView = new TableView<>();
// Create the TableColumn
TableColumn<Item, String> colName = new TableColumn<>("Name");
TableColumn<Item, String> colColor = new TableColumn<>("Color");
// Cell Property Factories
colName.setCellValueFactory(column -> new SimpleObjectProperty<>(column.getValue().getItemName()));
colColor.setCellValueFactory(column -> new SimpleObjectProperty<>(column.getValue().getItemColor()));
// Add ComboBox to the Color column, populated with the list of availableColors
colColor.setCellFactory(tc -> {
ComboBox<String> comboBox = new ComboBox<>(availableColors);
comboBox.setMaxWidth(Double.MAX_VALUE);
TableCell<Item, String> cell = new TableCell<Item, String>() {
@Override
protected void updateItem(String color, boolean empty) {
super.updateItem(color, empty);
if (empty) {
setGraphic(null);
} else {
setGraphic(comboBox);
comboBox.setValue(color);
}
}
};
// Set the action of the ComboBox to set the right Value to the ValuePair
comboBox.setOnAction(event -> {
listOfItems.get(cell.getIndex()).setItemColor(comboBox.getValue());
});
return cell;
});
// Add the column to the TableView
tableView.getColumns().addAll(colName, colColor);
tableView.setItems(listOfItems);
// Add button to load the data
Button btnLoadData = new Button("Load Available Colors");
btnLoadData.setOnAction(event -> {
buildSampleData();
});
root.getChildren().add(btnLoadData);
// Add the TableView to the root layout
root.getChildren().add(tableView);
Button btnPrintAll = new Button("Print All");
btnPrintAll.setOnAction(event -> {
for (Item item : listOfItems) {
System.out.println(item.getItemName() + " : " + item.getItemColor());
}
});
root.getChildren().add(btnPrintAll);
// Show the stage
primaryStage.setScene(new Scene(root));
primaryStage.setTitle("Sample");
primaryStage.show();
}
}
Main.java:
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Item {
private StringProperty itemName = new SimpleStringProperty();
private StringProperty itemColor = new SimpleStringProperty();
public Item(String name, String color) {
this.itemName.set(name);
this.itemColor.set(color);
}
public String getItemName() {
return itemName.get();
}
public void setItemName(String itemName) {
this.itemName.set(itemName);
}
public StringProperty itemNameProperty() {
return itemName;
}
public String getItemColor() {
return itemColor.get();
}
public void setItemColor(String itemColor) {
this.itemColor.set(itemColor);
}
public StringProperty itemColorProperty() {
return itemColor;
}
}
import javafx.application.Application;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
// List of items
private static ObservableList<Item> listOfItems = FXCollections.observableArrayList();
// List of available Colors. These will be selectable from the ComboBox
private static ObservableList<String> availableColors = FXCollections.observableArrayList();
public static void main(String[] args) {
launch(args);
}
private static void buildSampleData() {
availableColors.addAll("Red", "Blue", "Green", "Yellow", "Black");
}
@Override
public void start(Stage primaryStage) {
// Simple Interface
VBox root = new VBox(10);
root.setAlignment(Pos.CENTER);
root.setPadding(new Insets(10));
// Build a list of sample data. This data is loaded from my data model and passed to the constructor
// of this editor in my real application.
listOfItems.addAll(
new Item("One", "Black"),
new Item("Two", "Black"),
new Item("Three", null),
new Item("Four", "Green"),
new Item("Five", "Red")
);
// TableView to display the list of items
TableView<Item> tableView = new TableView<>();
// Create the TableColumn
TableColumn<Item, String> colName = new TableColumn<>("Name");
TableColumn<Item, String> colColor = new TableColumn<>("Color");
// Cell Property Factories
colName.setCellValueFactory(column -> new SimpleObjectProperty<>(column.getValue().getItemName()));
colColor.setCellValueFactory(column -> new SimpleObjectProperty<>(column.getValue().getItemColor()));
// Add ComboBox to the Color column, populated with the list of availableColors
colColor.setCellFactory(tc -> {
ComboBox<String> comboBox = new ComboBox<>(availableColors);
comboBox.setMaxWidth(Double.MAX_VALUE);
TableCell<Item, String> cell = new TableCell<Item, String>() {
@Override
protected void updateItem(String color, boolean empty) {
super.updateItem(color, empty);
if (empty) {
setGraphic(null);
} else {
setGraphic(comboBox);
comboBox.setValue(color);
}
}
};
// Set the action of the ComboBox to set the right Value to the ValuePair
comboBox.setOnAction(event -> {
listOfItems.get(cell.getIndex()).setItemColor(comboBox.getValue());
});
return cell;
});
// Add the column to the TableView
tableView.getColumns().addAll(colName, colColor);
tableView.setItems(listOfItems);
// Add button to load the data
Button btnLoadData = new Button("Load Available Colors");
btnLoadData.setOnAction(event -> {
buildSampleData();
});
root.getChildren().add(btnLoadData);
// Add the TableView to the root layout
root.getChildren().add(tableView);
Button btnPrintAll = new Button("Print All");
btnPrintAll.setOnAction(event -> {
for (Item item : listOfItems) {
System.out.println(item.getItemName() + " : " + item.getItemColor());
}
});
root.getChildren().add(btnPrintAll);
// Show the stage
primaryStage.setScene(new Scene(root));
primaryStage.setTitle("Sample");
primaryStage.show();
}
}
导入javafx.application.application;
导入javafx.beans.property.SimpleObject属性;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.geometry.Insets;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.*;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类主扩展应用程序{
//项目清单
私有静态ObservableList listOfItems=FXCollections.observableArrayList();
//可用颜色列表。可从组合框中选择这些颜色
私有静态ObservableList availableColors=FXCollections.observableArrayList();
公共静态void main(字符串[]args){
发射(args);
}
私有静态void buildSampleData(){
可用颜色。添加所有(“红色”、“蓝色”、“绿色”、“黄色”、“黑色”);
}
@凌驾
公共无效开始(阶段primaryStage){
//简单接口
VBox根=新的VBox(10);
根部设置对齐(位置中心);
根。设置填充(新插图(10));
//构建示例数据列表。此数据从我的数据模型加载并传递给构造函数
//在我的实际应用程序中使用此编辑器。
listOfItems.addAll(
新项目(“一”、“黑色”),
新项目(“两个”、“黑色”),
新项目(“三”,空),
新项目(“四”、“绿色”),
新项目(“五”、“红色”)
);
//TableView以显示项目列表
TableView TableView=新建TableView();
//创建TableColumn
TableColumn colName=新的TableColumn(“名称”);
TableColumn colColor=新的TableColumn(“颜色”);
//细胞特性工厂
colName.setCellValueFactory(列->新建SimpleObject属性(列.getValue().getItemName());
setCellValueFactory(column->newSimpleObject属性(column.getValue().getItemColor());
//将组合框添加到“颜色”列,并填充可用颜色列表
colColor.setCellFactory(tc->{
ComboBox ComboBox=新的ComboBox(可用颜色);
comboBox.setMaxWidth(Double.MAX_值);
TableCell单元格=新的TableCell(){
@凌驾
受保护的void updateItem(字符串颜色,布尔值为空){
super.updateItem(颜色,空);
if(空){
设置图形(空);
}否则{
设置图形(组合框);
comboBox.setValue(颜色);
}
}
};
//设置ComboBox的操作以将正确的值设置为ValuePair
comboBox.setOnAction(事件->{
获取(cell.getIndex()).setItemColor(comboBox.getValue());
});
返回单元;
});
//将列添加到TableView
tableView.getColumns().addAll(colName,colColor);
tableView.setItems(列表项);
//添加按钮以加载数据
按钮btnLoadData=新按钮(“加载可用颜色”);
btnLoadData.setOnAction(事件->{
buildSampleData();
});
root.getChildren().add(btnLoadData);
//将TableView添加到根布局
root.getChildren().add(tableView);
按钮BTNPRITALL=新按钮(“全部打印”);
btnPrintAll.setOnAction(事件->{
用于(项目:列表项){
System.out.println(item.getItemName()+”:“+item.getItemColor());
}
});
root.getChildren().add(btnPrintAll);
//上台
primaryStage.setScene(新场景(根));
初级阶段。设置标题(“样本”);
primaryStage.show();
}
}
现在,使用常规的组合框
,在加载可用颜色
后,只需简单调用组合框.getSelectionModel().selectFirst()
。但是由于这个组合框是在CellFactory中创建的,我不知道填充颜色列表后如何更新它
另外,我使用这个CellFactory
实现而不是ComboBoxTableCell
,因为我希望它们不必在TableView
上进入编辑模式就可以看到
实际上,我接受了克利奥帕特拉的建议,更新了我的数据模型,以包含一个默认值。我同意这是一种更干净、更合适的方法。我不太明白:表中的项没有空值,所以组合