TableView,用于定义自定义编辑行为的不兼容类型

时间:2015-02-01 13:45:22

标签: type-conversion tableview javafx-8

(我有点踩到黑暗中,所以请原谅我,如果我写的东西不够清楚,只是要求提供更多信息。)

我有一个DataModel,我用作TableView的数据。 DataModel包含name,surname,age和tel的String和Integer数据。数。

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类进行自定义单元格编辑事件时(如此处所述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进行数据类,之后只进行一些转换吗?

编辑: 这是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();
}

}

1 个答案:

答案 0 :(得分:0)

我认为第二个错误(ageColumn.setOnEditCommit(...))仅在您的IDE中出现第一个错误。当我自己尝试时它对我来说很好。

我无法重新创建第一个错误,因为您没有发布EditingCell;但是你在这里显然有不匹配的类型。 TableColumn<S,T>定义了setCellFactory(Callback<TableColumn<S,T>, TableCell<S,T>>)方法。对于ageColumn,类型为S=DataModelT=Integer,因此您需要传递Callback<TableColumn<DataModel, Integer>, TableCell<DataModel, Integer>>,这不是您为cellFactory声明的类型。我假设EditingCellTableCell<String>的子类(否则cellFactory的声明将无法编译)。您需要创建另一个类(例如AgeCell),它是TableCell<Integer>的子类,然后执行

Callback<TableColumn<DataModel, Integer>, TableCell<DataModel, Integer>> ageCellFactory = (TableColumn<DataModel, Integer> col) -> new AgeCell();

根据您EditingCell的实施方式,以及您需要了解单元格中对象类型的数量,您可以将其设为通用类:

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,并将数据模型值转换为值待显示。

  

我想知道最好只使用SimpleStringProperties   数据类以及稍后只进行一些转换?

绝对不是。 JavaFX中的所有内容(几乎)都设置为通用的,因此您应该利用它并在数据模型中使用适当的类型。