TableView,用于定义自定义编辑行为的不兼容类型
TableView, incompatible types for defining custom editing behaviour
(我有点摸不着头脑,所以如果我写的不够清楚,请多多包涵。)
我有一个数据模型,用作我的 TableView 的数据。 DataModel 包含名称、姓氏、年龄和电话的字符串和整数数据。数字。
public class DataModel {
private SimpleStringProperty sName;
private SimpleStringProperty sSurname;
private SimpleIntegerProperty iAge;
private SimpleIntegerProperty iPhoneNumber;
public DataModel(String sName, String sSurname, int iAge, int iPhoneNumber) {
this.sName = new SimpleStringProperty(sName);
this.sSurname = new SimpleStringProperty(sSurname);
this.iAge = new SimpleIntegerProperty(iAge);
this.iPhoneNumber = new SimpleIntegerProperty(iPhoneNumber);
}
//...getters and setters..
当我使用 EditingCell 进行自定义单元格编辑事件时 class(如此处所述 Oracle Tutorial
) 它适用于 DataModel 的 SimpleStringProperties 而不适用于 SimpleIntegerValues:
Callback<TableColumn<DataModel, String>, TableCell<DataModel, String>> cellFactory = (TableColumn<DataModel, String> p) -> new EditingCell();
surnameColumn.setCellFactory(TextFieldTableCell.<DataModel>forTableColumn());
surnameColumn.setCellFactory(cellFactory);
surnameColumn.setOnEditCommit((CellEditEvent<DataModel, String> event) -> {
((DataModel) event.getTableView().getItems(). get(event.getTablePosition().getRow())). setsSurname(event.getNewValue());
});
ageColumn.setCellFactory(TextFieldTableCell.<DataModel, Integer>forTableColumn(new IntegerStringConverter()));
X ageColumn.setCellFactory(cellFactory); //dodajemy custom editing event
XX ageColumn.setOnEditCommit((CellEditEvent<DataModel, Integer> event) -> {
((DataModel) event.getTableView().getItems(). get(event.getTablePosition().getRow())). setiAge(event.getNewValue());
});
X 是编译器向我发送错误的地方:
The method setCellFactory(Callback<TableColumn<DataModel,Integer>,TableCell<DataModel,Integer>>) in the type TableColumn<DataModel,Integer> is not applicable for the arguments (Callback<TableColumn<DataModel,String>,TableCell<DataModel,String>>)
XX 是编译器向我发送错误的地方:
The method setOnEditCommit(EventHandler<TableColumn.CellEditEvent<DataModel,Integer>>) in the type TableColumn<DataModel,Integer> is not applicable for the arguments ((CellEditEvent<DataModel, Integer> event) -> {})
互联网上似乎没有太多关于使用 TableView 的资料。除了上面的这些错误,我想知道是否最好只对数据使用 SimpleStringProperties Class 然后再做一些转换?
编辑:
这是 EditingCell 的实现。
package application;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TableCell;
import javafx.scene.control.TextField;
//Klasa ta pozwala na definiowania zachowania komórek, które edytuje użytkownik
public class EditingCell extends TableCell<DataModel, String>{
private TextField textField;
public EditingCell() {
}
@Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
createTextField();
setText(null);
setGraphic(textField);
textField.selectAll();
}
}
@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()) {
if (textField != null) {
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(null);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()* 2);
textField.focusedProperty().addListener(
(ObservableValue<? extends Boolean> arg0,
Boolean arg1, Boolean arg2) -> {
if (!arg2) {
commitEdit(textField.getText());
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
我认为第二个错误 (ageColumn.setOnEditCommit(...)
) 只是由于第一个错误而出现在您的 IDE 中。当我自己尝试时,它对我来说效果很好。
我无法重现第一个错误,因为你没有 post EditingCell
;但是你显然在这里有不匹配的类型。 TableColumn<S,T>
定义了一个 setCellFactory(Callback<TableColumn<S,T>, TableCell<S,T>>)
方法。对于你的 ageColumn
,类型是 S=DataModel
和 T=Integer
,所以你需要传递一个 Callback<TableColumn<DataModel, Integer>, TableCell<DataModel, Integer>>
,这不是你为 cellFactory
声明的类型.我假设 EditingCell
是 TableCell<String>
的子 class(否则 cellFactory
的声明将无法编译)。您需要创建另一个 class(比如 AgeCell
),它是 TableCell<Integer>
的子 class,然后执行
Callback<TableColumn<DataModel, Integer>, TableCell<DataModel, Integer>> ageCellFactory = (TableColumn<DataModel, Integer> col) -> new AgeCell();
根据您的 EditingCell
的实现方式,以及您需要对单元格中的对象类型了解多少,您可以将其设为通用 class:
public class EditingCell<T> extends TableCell<DataModel, T> {
@Override
public void updateItem(T item, boolean empty) {
// ...
}
// ...
}
然后你可以做
surnameCol.setCellFactory(column -> new EditingCell<String>());
ageCol.setCellFactory(column -> new EditingCell<Integer>());
在不了解您的 EditingCell
实现的情况下,很难知道这是否是一个可行的选择。 EditingCell
可能需要传递 StringConverter<T>
以将值从 TextField
转换为要提供给 DataModel
的值,并将数据模型值转换为值待展示。
I wonder is it best generaly to use only SimpleStringProperties for
Data Class and later just do some conversions?
绝对不是。 JavaFX 中的所有内容(几乎)都设置为通用的,因此您应该利用这一点并在数据模型中使用适当的类型。
(我有点摸不着头脑,所以如果我写的不够清楚,请多多包涵。)
我有一个数据模型,用作我的 TableView 的数据。 DataModel 包含名称、姓氏、年龄和电话的字符串和整数数据。数字。
public class DataModel {
private SimpleStringProperty sName;
private SimpleStringProperty sSurname;
private SimpleIntegerProperty iAge;
private SimpleIntegerProperty iPhoneNumber;
public DataModel(String sName, String sSurname, int iAge, int iPhoneNumber) {
this.sName = new SimpleStringProperty(sName);
this.sSurname = new SimpleStringProperty(sSurname);
this.iAge = new SimpleIntegerProperty(iAge);
this.iPhoneNumber = new SimpleIntegerProperty(iPhoneNumber);
}
//...getters and setters..
当我使用 EditingCell 进行自定义单元格编辑事件时 class(如此处所述 Oracle Tutorial ) 它适用于 DataModel 的 SimpleStringProperties 而不适用于 SimpleIntegerValues:
Callback<TableColumn<DataModel, String>, TableCell<DataModel, String>> cellFactory = (TableColumn<DataModel, String> p) -> new EditingCell();
surnameColumn.setCellFactory(TextFieldTableCell.<DataModel>forTableColumn());
surnameColumn.setCellFactory(cellFactory);
surnameColumn.setOnEditCommit((CellEditEvent<DataModel, String> event) -> {
((DataModel) event.getTableView().getItems(). get(event.getTablePosition().getRow())). setsSurname(event.getNewValue());
});
ageColumn.setCellFactory(TextFieldTableCell.<DataModel, Integer>forTableColumn(new IntegerStringConverter()));
X ageColumn.setCellFactory(cellFactory); //dodajemy custom editing event
XX ageColumn.setOnEditCommit((CellEditEvent<DataModel, Integer> event) -> {
((DataModel) event.getTableView().getItems(). get(event.getTablePosition().getRow())). setiAge(event.getNewValue());
});
X 是编译器向我发送错误的地方:
The method setCellFactory(Callback<TableColumn<DataModel,Integer>,TableCell<DataModel,Integer>>) in the type TableColumn<DataModel,Integer> is not applicable for the arguments (Callback<TableColumn<DataModel,String>,TableCell<DataModel,String>>)
XX 是编译器向我发送错误的地方:
The method setOnEditCommit(EventHandler<TableColumn.CellEditEvent<DataModel,Integer>>) in the type TableColumn<DataModel,Integer> is not applicable for the arguments ((CellEditEvent<DataModel, Integer> event) -> {})
互联网上似乎没有太多关于使用 TableView 的资料。除了上面的这些错误,我想知道是否最好只对数据使用 SimpleStringProperties Class 然后再做一些转换?
编辑: 这是 EditingCell 的实现。
package application;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TableCell;
import javafx.scene.control.TextField;
//Klasa ta pozwala na definiowania zachowania komórek, które edytuje użytkownik
public class EditingCell extends TableCell<DataModel, String>{
private TextField textField;
public EditingCell() {
}
@Override
public void startEdit() {
if (!isEmpty()) {
super.startEdit();
createTextField();
setText(null);
setGraphic(textField);
textField.selectAll();
}
}
@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()) {
if (textField != null) {
textField.setText(getString());
}
setText(null);
setGraphic(textField);
} else {
setText(getString());
setGraphic(null);
}
}
}
private void createTextField() {
textField = new TextField(getString());
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()* 2);
textField.focusedProperty().addListener(
(ObservableValue<? extends Boolean> arg0,
Boolean arg1, Boolean arg2) -> {
if (!arg2) {
commitEdit(textField.getText());
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
}
我认为第二个错误 (ageColumn.setOnEditCommit(...)
) 只是由于第一个错误而出现在您的 IDE 中。当我自己尝试时,它对我来说效果很好。
我无法重现第一个错误,因为你没有 post EditingCell
;但是你显然在这里有不匹配的类型。 TableColumn<S,T>
定义了一个 setCellFactory(Callback<TableColumn<S,T>, TableCell<S,T>>)
方法。对于你的 ageColumn
,类型是 S=DataModel
和 T=Integer
,所以你需要传递一个 Callback<TableColumn<DataModel, Integer>, TableCell<DataModel, Integer>>
,这不是你为 cellFactory
声明的类型.我假设 EditingCell
是 TableCell<String>
的子 class(否则 cellFactory
的声明将无法编译)。您需要创建另一个 class(比如 AgeCell
),它是 TableCell<Integer>
的子 class,然后执行
Callback<TableColumn<DataModel, Integer>, TableCell<DataModel, Integer>> ageCellFactory = (TableColumn<DataModel, Integer> col) -> new AgeCell();
根据您的 EditingCell
的实现方式,以及您需要对单元格中的对象类型了解多少,您可以将其设为通用 class:
public class EditingCell<T> extends TableCell<DataModel, T> {
@Override
public void updateItem(T item, boolean empty) {
// ...
}
// ...
}
然后你可以做
surnameCol.setCellFactory(column -> new EditingCell<String>());
ageCol.setCellFactory(column -> new EditingCell<Integer>());
在不了解您的 EditingCell
实现的情况下,很难知道这是否是一个可行的选择。 EditingCell
可能需要传递 StringConverter<T>
以将值从 TextField
转换为要提供给 DataModel
的值,并将数据模型值转换为值待展示。
I wonder is it best generaly to use only SimpleStringProperties for Data Class and later just do some conversions?
绝对不是。 JavaFX 中的所有内容(几乎)都设置为通用的,因此您应该利用这一点并在数据模型中使用适当的类型。