JavaFX中tableview单元格中的ComboBox
我正在尝试在我的Table View
添加一个Combo Box
:
基本上我有一个名为TableViewTest的类,它存储了一个名称和一个描述,我可以在Table View
显示这些名称和描述没有麻烦,但我想要做的是添加第三列,每个单元格都有一个Combo Box
以便用户可以从每个人的多个选项中选择一个。
到目前为止,我已经创建了一个带有一些值的String
类型的ObservableList
,并将它们添加到ComboBox
对象中。 有谁知道我将这个Combo Box
添加到表中的方法?
另外请记住,这段代码非常粗糙,我只想尝试一些工作,我将在以后重构代码。
ObservableList products = FXCollections.observableArrayList(); for(int i = 0; i < b.length; i++){ // random String values products.add(new TableViewTest(b[i], a[i])); } ObservableList options = FXCollections.observableArrayList( "1", "2", "3" ); final ComboBox comboBox = new ComboBox(options); TableColumn nameColumn = new TableColumn ("Name"); nameColumn.setMinWidth(200); nameColumn.setCellValueFactory(new PropertyValueFactory("name")); //price Column //Stock Column TableColumn StockColumn = new TableColumn ("Stock"); StockColumn.setMinWidth(150); StockColumn.setCellValueFactory(new PropertyValueFactory("description")); TableColumn PriceColumn; PriceColumn = new TableColumn("Source"); PriceColumn.setMinWidth(150); //PriceColumn.setCellValueFactory(new PropertyValueFactory //(options)); //PriceColumn.setCellFactory(ComboBoxTableCell.forTableColumn(new //DefaultStringConverter(), options)); //PriceColumn.setCellFactory(ComboBoxTableCell.forTableColumn( //comboBox)); TableView table = new TableView(); table.setItems(products); table.getColumns().addAll(nameColumn, StockColumn, PriceColumn);
James_D的答案很有效,但要求用户点击该项目才能看到ComboBox
。 如果您希望在列中始终显示ComboBox
,则必须使用自定义cellFactory
:
例:
public class TableViewTest { ... private final StringProperty option = new SimpleStringProperty(); public String getOption() { return option.get(); } public void setOption(String value) { option.set(value); } public StringProperty optionProperty() { return option; } }
TableColumn column = new TableColumn<>("option"); column.setCellValueFactory(i -> { final StringProperty value = i.getValue().optionProperty(); // binding to constant value return Bindings.createObjectBinding(() -> value); }); column.setCellFactory(col -> { TableCell c = new TableCell<>(); final ComboBox comboBox = new ComboBox<>(options); c.itemProperty().addListener((observable, oldValue, newValue) -> { if (oldValue != null) { comboBox.valueProperty().unbindBidirectional(oldValue); } if (newValue != null) { comboBox.valueProperty().bindBidirectional(newValue); } }); c.graphicProperty().bind(Bindings.when(c.emptyProperty()).then((Node) null).otherwise(comboBox)); return c; });
表列的类型始终是第一个类型参数中每行中项目的类型(即与用于表视图的类型相同),以及每个单元格中的(当前)值的类型。第二个参数的列。 因此,如果您的表视图具有类型TableViewTest
,并且您的combobox正在选择String
s,那么您应该拥有
TableColumn priceColumn ;
单元格值工厂仍应映射到TableViewTest
类中的属性,即假设您具有
public class TableViewTest { // ... public StringProperty priceProperty() { // ... } // ... }
那么你可以做到
priceColumn.setCellValueFactory(new PropertyValueFactory<>("price""));
或者(好多了)
priceColumn.setCellValueFactory(cellData -> cellData.getValue().priceProperty());
那你就可以做到
priceColumn.setCellFactory(ComboBoxTableCell.forTableColumn(options));
这是一个SSCCE:
import javafx.application.Application; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.scene.Scene; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.cell.ComboBoxTableCell; import javafx.scene.control.cell.TextFieldTableCell; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; public class TableWithComboBoxExample extends Application { @Override public void start(Stage primaryStage) { TableView contactTable = new TableView<>(); contactTable.setEditable(true); TableColumn nameCol = new TableColumn<>("Name"); nameCol.setCellValueFactory(cellData -> cellData.getValue().nameProperty()); nameCol.setCellFactory(TextFieldTableCell.forTableColumn()); contactTable.getColumns().add(nameCol); TableColumn categoryCol = new TableColumn<>("Category"); categoryCol.setCellValueFactory(cellData -> cellData.getValue().categoryProperty()); categoryCol.setCellFactory(ComboBoxTableCell.forTableColumn("Friends", "Family", "Work Contacts")); contactTable.getColumns().add(categoryCol); contactTable.getItems().addAll( new Contact("Bill Gates", "Work Contacts"), new Contact("Barack Obama", "Friends"), new Contact("Tim Cook", "Work Contacts") ); Scene scene = new Scene(new BorderPane(contactTable), 600, 600); primaryStage.setScene(scene); primaryStage.show(); } public static class Contact { private final StringProperty name = new SimpleStringProperty(); private final StringProperty category = new SimpleStringProperty(); public Contact(String name, String category) { setName(name); setCategory(category); } public final StringProperty nameProperty() { return this.name; } public final String getName() { return this.nameProperty().get(); } public final void setName(final String name) { this.nameProperty().set(name); } public final StringProperty categoryProperty() { return this.category; } public final String getCategory() { return this.categoryProperty().get(); } public final void setCategory(final String category) { this.categoryProperty().set(category); } } public static void main(String[] args) { launch(args); } }