在我的TableView中,ComboBoxTableCell需要在每一行中具有不同的内容。我已修改了Uluk Biy在此问题中建议的代码:Populate combo box list dynamically for each row in javaFx table view。我的代码如下所示。
对我来说,问题是我实际上无法在ComboBox中进行其他选择。在上面提到的问题中,这也是一个问题。
一个建议的解决方案是:' ...从组合框更改值之后,单元格仍处于编辑模式,您需要从单元格中移出焦点,因此combobox.focusProperty可以commitEdit。或者,您可以根据需要将commitEdit()放在组合框项目changeListener上。'。有人可以给我一个想法,或者以其他方式帮助我使我的代码正常工作吗?
此外,即使用户动态更改列宽,如何使ComboBox适应单元格的宽度?
我当前的代码:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.stage.Stage;
import javafx.util.Callback;
public class ComboBoxCellTableExample extends Application {
private final TableView<Attribute> table = new TableView<>();
private Attribute attribute1 = new Attribute("2222", "attribute1", "1111|2222|3333");
private Attribute attribute2 = new Attribute("bbbb", "attribute2", "aaaa|bbbb|cccc");
private Attribute attribute3 = new Attribute("6666", "attribute3", "4444|5555|6666");
private Attribute attribute4 = new Attribute("7777", "attribute4", "7777|8888|99999");
private Attribute attribute5 = new Attribute("hhhh", "attribute5", "hhhh|jjjj|kkkk");
private final ObservableList<Attribute> data
= FXCollections.observableArrayList(attribute1, attribute2, attribute3, attribute4, attribute5);
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setWidth(800);
stage.setHeight(550);
table.setEditable(true);
table.setMinWidth(750.0);
TableColumn colName = new TableColumn("Name");
colName.setMinWidth(100);
colName.setEditable(false);
colName.setCellValueFactory(new PropertyValueFactory<>("name"));
colName.setCellFactory(TextFieldTableCell.forTableColumn());
Callback<TableColumn, TableCell> cellFactory = new Callback<TableColumn, TableCell>() {
@Override
public TableCell call(TableColumn p) {
return new ComboBoxCell();
}
};
TableColumn colValue = new TableColumn("Value");
colValue.setMinWidth(100);
colValue.setCellValueFactory(new PropertyValueFactory<>("value"));
colValue.setCellFactory(cellFactory);
colValue.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Attribute, String>>() {
@Override
public void handle(TableColumn.CellEditEvent<Attribute, String> tableColumn) {
((Attribute) tableColumn.getTableView().getItems().
get(tableColumn.getTablePosition().getRow())).setValue(tableColumn.getNewValue());
}
});
table.setItems(data);
table.getColumns().addAll(colName, colValue);
((Group) scene.getRoot()).getChildren().add(table);
stage.setScene(scene);
stage.show();
}
class ComboBoxCell extends TableCell<Attribute, String> {
private ComboBox<String> comboBox;
public ComboBoxCell() {
comboBox = new ComboBox<>();
}
@Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
comboBox.setItems(getTableView().getItems().get(getIndex()).getOptionsList());
comboBox.getSelectionModel().select(getItem());
comboBox.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue,
Boolean newValue) {
if (newValue) {
commitEdit(comboBox.getSelectionModel().getSelectedItem());
}
}
});
setText(null);
setGraphic(comboBox);
}
}
@Override
public void cancelEdit() {
super.cancelEdit();
setText((String) getItem());
setGraphic(null);
}
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
setText(null);
setGraphic(comboBox);
} else {
setText(getItem());
setGraphic(null);
}
}
}
}
public static void main(String[] args) {
launch(args);
}
public class Attribute {
private String value;
private String name;
private String options;
private ObservableList<String> optionsList;
private Attribute(String value, String name, String options) {
this.value = value;
this.name = name;
this.options = options;
this.optionsList = parseOptions(options);
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ObservableList<String> getOptionsList() {
return optionsList;
}
public void setOptionsList(ObservableList<String> optionsList) {
this.optionsList = optionsList;
}
public void setOptions(String options) {
this.options = options;
}
public String getOptions() {
return options;
}
public ObservableList<String> parseOptions(String options) {
ObservableList<String> model = FXCollections.observableArrayList();
int startPos = 0;
int endPos = 0;
while (endPos >= 0) {
endPos = options.indexOf('|', startPos);
if (endPos >= 0) {
model.add(options.substring(startPos, endPos));
startPos = endPos + 1;
} else {
model.add(options.substring(startPos, options.length()));
}
}
return model;
}
}
}
任何能帮助我完成此代码的评论都将不胜感激。
关于Stuart M