JavaFX表格单元格编辑
我正在尝试用Java编写一个程序来管理我的博彩帐户。我是java新手,所以我想我应该选择一些简单的东西来看看它是如何工作的。我决定使用tableview并使单个单元格可编辑。我一直在学习这个教程。它详细介绍了如何使用java代码来实现这一点,并将其复制到一个新类中。因为我喜欢Sceneviewer,所以我决定尝试调整它以与FXML一起使用。我的问题是,数据被加载到表中,但当我单击/双击单元格时,什么也没有发生。这是我的密码 testController.javaJavaFX表格单元格编辑,java,javafx,tableview,scenebuilder,Java,Javafx,Tableview,Scenebuilder,我正在尝试用Java编写一个程序来管理我的博彩帐户。我是java新手,所以我想我应该选择一些简单的东西来看看它是如何工作的。我决定使用tableview并使单个单元格可编辑。我一直在学习这个教程。它详细介绍了如何使用java代码来实现这一点,并将其复制到一个新类中。因为我喜欢Sceneviewer,所以我决定尝试调整它以与FXML一起使用。我的问题是,数据被加载到表中,但当我单击/双击单元格时,什么也没有发生。这是我的密码 testController.java import javafx.co
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<Account, String> usernameCol;
@FXML
private TableColumn<Account, String> balanceCol;
@FXML
private TableView<Account> accountTable;
@FXML
private TableColumn<Account, String> bookieCol;
@FXML
private TableColumn<Account, String> passwordCol;
private ObservableList<Account> dataList =
FXCollections.observableArrayList(
new Account("bookie", "username", "password", "0"));
@Override
public void initialize(URL location, ResourceBundle resources) {
Callback<TableColumn, TableCell> cellFactory =
new Callback<TableColumn, TableCell>() {
public TableCell call(TableColumn p) {
return new EditingCell();
}
};
bookieCol.setCellValueFactory(
new PropertyValueFactory<>("fieldBookie"));
usernameCol.setCellValueFactory(
new PropertyValueFactory<>("fieldUsername"));
usernameCol.setOnEditCommit(
new EventHandler<TableColumn.CellEditEvent<Account, String>>() {
@Override public void handle(TableColumn.CellEditEvent<Account, String> t) {
((Account)t.getTableView().getItems().get(
t.getTablePosition().getRow())).setFieldUsername(t.getNewValue());
}
});
passwordCol.setCellValueFactory(
new PropertyValueFactory<Account, String>("fieldPassword"));
balanceCol.setCellValueFactory(
new PropertyValueFactory<Account, String>("fieldBalance"));
accountTable.setItems(dataList);
}
class EditingCell extends TableCell<Account, String> {
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();
}
}
}
最后,这里是我的fxml文件
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.canvas.*?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<Group xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="testController">
<children>
<TableView fx:id="accountTable" editable="true" prefHeight="291.0" prefWidth="302.0">
<columns>
<TableColumn fx:id="bookieCol" prefWidth="75.0" text="Bookie" />
<TableColumn fx:id="usernameCol" prefWidth="75.0" text="Username" />
<TableColumn fx:id="passwordCol" prefWidth="75.0" text="Password" />
<TableColumn fx:id="balanceCol" prefWidth="75.0" text="Balance" />
</columns>
</TableView>
</children>
</Group>
正如我前面所说的,当我点击Username单元格时,什么也没有发生。没有错误,没有文本字段,什么都没有。
任何帮助都将不胜感激!谢谢我没有试过你的例子,但我想你只是忘记了为特定列设置cellFactory。添加以下行应该可以解决此问题:
usernameCol.setCellFactory(cellFactory);
您可以使用:
TextFieldTableCell.forTableColumn()将textField添加到编辑单元格中代码>
如果需要comboBox,请尝试:ComboBoxTableCell.forTableColumn(列表)代码>
//文本字段:
usernameCol.setCellFactory(TextFieldTableCell.forTableColumn());
//组合框:
ObservableList=FXCollections.observableArrayList();
列表。添加(“名称1”);
列表。添加(“名称2”);
列表。添加(“名称3”);
列表。添加(“名称4”);
回调cbtc=
ComboBoxTableCell.forTableColumn(列表);
usernameCol.setCellFactory(cbtc);
如果有人需要一个工作示例,我可以通过添加
usernameCol.setCellFactory(
TextFieldTableCell.forTableColumn());
并将usernameCol.setOnEditCommit
更改为
usernameCol.setOnEditCommit(
(TableColumn.CellEditEvent<Account, String> t) ->
( t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setFieldUsername(t.getNewValue())
);
这是正确的,但是您还需要修复类型(Callback
etc)。这种方法有点传统:您可以执行usernameCol.setCellFactory(TextFieldTableCell.forTableColumn())
然后扔掉编辑单元
好的,谢谢,我现在就试试。关于javafx和可编辑表的教程不多,遗憾的是:(这不是很好,但涵盖了基础知识。它工作得很好,我也删除了编辑单元格类!代码更少,对我来说更容易理解!谢谢两者。@OrdinaryDraft您可能想看看这里:。我面临着同样的挑战,不幸的是,这不是一件容易实现的事情。不确定是否有更好的方法,但kleopatra能够提供体面的解决方案。
usernameCol.setOnEditCommit(
(TableColumn.CellEditEvent<Account, String> t) ->
( t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setFieldUsername(t.getNewValue())
);
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<Account, String> usernameCol;
@FXML
private TableColumn<Account, String> balanceCol;
@FXML
private TableView<Account> accountTable;
@FXML
private TableColumn<Account, String> bookieCol;
@FXML
private TableColumn<Account, String> passwordCol;
private ObservableList<Account> 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<Account, String> t) ->
( t.getTableView().getItems().get(
t.getTablePosition().getRow())
).setFieldUsername(t.getNewValue())
);
passwordCol.setCellValueFactory(
new PropertyValueFactory<Account, String>("fieldPassword"));
balanceCol.setCellValueFactory(
new PropertyValueFactory<Account, String>("fieldBalance"));
accountTable.setItems(dataList);
}
}