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