JavaFX表格单元格编辑

我正在尝试用Java创建一个程序来管理我的bookie帐户。 我是java的新手,所以我想我会选择一些简单的东西来看看它是如何工作的。 我决定使用tableview并使单个单元格可编辑。 我一直在关注这个教程http://java-buddy.blogspot.co.uk/2012/04/javafx-2-editable-tableview.html 。 它详细介绍了如何使用java代码进行操作,并将其复制到新类中可以完美地运行。 我决定尝试调整它以使用FXML,因为我喜欢Sceneviewer。 我的问题是,数据被加载到表中,但是当我单击/双击一个单元格时,没有任何反应。 这是我的代码。

testController.java

import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.*; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.util.Callback; import java.net.URL; import java.util.ResourceBundle; public class testController implements Initializable { @FXML private TableColumn usernameCol; @FXML private TableColumn balanceCol; @FXML private TableView accountTable; @FXML private TableColumn bookieCol; @FXML private TableColumn passwordCol; private ObservableList dataList = FXCollections.observableArrayList( new Account("bookie", "username", "password", "0")); @Override public void initialize(URL location, ResourceBundle resources) { Callback cellFactory = new Callback() { public TableCell call(TableColumn p) { return new EditingCell(); } }; bookieCol.setCellValueFactory( new PropertyValueFactory("fieldBookie")); usernameCol.setCellValueFactory( new PropertyValueFactory("fieldUsername")); usernameCol.setOnEditCommit( new EventHandler<TableColumn.CellEditEvent>() { @Override public void handle(TableColumn.CellEditEvent t) { ((Account)t.getTableView().getItems().get( t.getTablePosition().getRow())).setFieldUsername(t.getNewValue()); } }); passwordCol.setCellValueFactory( new PropertyValueFactory("fieldPassword")); balanceCol.setCellValueFactory( new PropertyValueFactory("fieldBalance")); accountTable.setItems(dataList); } class EditingCell extends TableCell { private TextField textField; public EditingCell() { } @Override public void startEdit() { super.startEdit(); if (textField == null) { createTextField(); } setGraphic(textField); setContentDisplay(ContentDisplay.GRAPHIC_ONLY); textField.selectAll(); } @Override public void cancelEdit() { super.cancelEdit(); setText(String.valueOf(getItem())); setContentDisplay(ContentDisplay.TEXT_ONLY); } @Override public void updateItem(String item, boolean empty) { super.updateItem(item, empty); if (empty) { setText(null); setGraphic(textField); } else { if (isEditing()) { if (textField != null) { textField.setText(getString()); } setGraphic(textField); setContentDisplay(ContentDisplay.GRAPHIC_ONLY); } else { setText(getString()); setContentDisplay(ContentDisplay.TEXT_ONLY); } } } private void createTextField() { textField = new TextField(getString()); textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2); textField.setOnKeyPressed(t -> { if (t.getCode() == KeyCode.ENTER) { commitEdit(textField.getText()); } else if (t.getCode() == KeyCode.ESCAPE) { cancelEdit(); } }); } private String getString() { return getItem() == null ? "" : getItem(); } } } 

这是我的Account.java文件。

 import javafx.beans.property.SimpleStringProperty; public class Account { private SimpleStringProperty fieldBookie; private SimpleStringProperty fieldUsername; private SimpleStringProperty fieldPassword; private SimpleStringProperty fieldBalance; Account(String fbookie, String fusername, String fpassword, String fbalance){ this.fieldBookie = new SimpleStringProperty(fbookie); this.fieldUsername = new SimpleStringProperty(fusername); this.fieldPassword = new SimpleStringProperty(fpassword); this.fieldBalance = new SimpleStringProperty(fbalance); } public String getFieldBookie() { return fieldBookie.get(); } public String getFieldUsername() { return fieldUsername.get(); } public String getFieldPassword() { return fieldPassword.get(); } public String getFieldBalance() { return fieldBalance.get(); } public void setFieldBookie(String fBookie) { fieldBookie.set(fBookie); } public void setFieldUsername(String fUsername) { fieldUsername.set(fUsername); } public void setFieldPassword(String fPassword) { fieldUsername.set(fPassword); } public void setFieldBalance(String fBalance) { fieldUsername.set(fBalance); } } 

最后,这是我的fxml文件。

                  

正如我之前所说,当我点击用户名单元格时没有任何反应。 没有错误,没有文本字段,什么也没有。 任何帮助将不胜感激! 谢谢

我没有试过你的例子,但我想你只是忘了为特定列设置cellFactory。 添加以下行应修复它:

 usernameCol.setCellFactory(cellFactory); 

我的情况是有人需要一个有效的例子,我能够通过添加一个代码来使用本教程

 usernameCol.setCellFactory( TextFieldTableCell.forTableColumn()); 

并将usernameCol.setOnEditCommit更改为

 usernameCol.setOnEditCommit( (TableColumn.CellEditEvent t) -> ( t.getTableView().getItems().get( t.getTablePosition().getRow()) ).setFieldUsername(t.getNewValue()) ); 

这是应该正常工作的完整testController类(其他文件保持不变)

 import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.control.cell.TextFieldTableCell; import java.net.URL; import java.util.ResourceBundle; public class testController implements Initializable { @FXML private TableColumn usernameCol; @FXML private TableColumn balanceCol; @FXML private TableView accountTable; @FXML private TableColumn bookieCol; @FXML private TableColumn passwordCol; private ObservableList dataList = FXCollections.observableArrayList( new Account("bookie", "username", "password", "0")); @Override public void initialize(URL location, ResourceBundle resources) { bookieCol.setCellValueFactory( new PropertyValueFactory<>("fieldBookie")); usernameCol.setCellValueFactory( new PropertyValueFactory<>("fieldUsername")); usernameCol.setCellFactory( TextFieldTableCell.forTableColumn()); usernameCol.setOnEditCommit( (TableColumn.CellEditEvent t) -> ( t.getTableView().getItems().get( t.getTablePosition().getRow()) ).setFieldUsername(t.getNewValue()) ); passwordCol.setCellValueFactory( new PropertyValueFactory("fieldPassword")); balanceCol.setCellValueFactory( new PropertyValueFactory("fieldBalance")); accountTable.setItems(dataList); } } 

您可以使用以下方法将textField添加到编辑单元格: TextFieldTableCell.forTableColumn(); 如果需要comboBox,请尝试: ComboBoxTableCell.forTableColumn(list);

 // TextField usernameCol.setCellFactory(TextFieldTableCell.forTableColumn()); //ComboBox ObservableList list = FXCollections.observableArrayList(); list.add("name 1"); list.add("name 2"); list.add("name 3"); list.add("name 4"); Callback, TableCell> cbtc = ComboBoxTableCell.forTableColumn(list); 

usernameCol.setCellFactory(CBTC);