如何在嵌套对象的tableview中显示数据?

7qhs6swi  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(370)

这个问题在这里已经有了答案

访问javafx tableview/tablecolumn中的嵌套属性(1个答案)
6天前关门。
我有一个 TableView<Marriage> 在控制器的类中:

public class MarriageTableView extends AbstractTableViewController {

    @FXML
    private TableView<Marriage> tableView;

    @FXML
    private TableColumn<Groom, String> groomFirstNameColumn,  groomLastNameColumn;

    @FXML
    private TableColumn<Bride, String> brideFirstNameColumn, brideLastNameColumn;

    @FXML
    private TableColumn<Marriage, LocalDate> marriageDateColumn;

    @FXML
    void initialize() {
        this.groomFirstNameColumn.setCellValueFactory(new PropertyValueFactory<Groom, String>("firstName")); // <- Exception here
        this.groomLastNameColumn.setCellValueFactory(new PropertyValueFactory<Groom, String>("lastName"));
        this.brideFirstNameColumn.setCellValueFactory(new PropertyValueFactory<Bride, String>("firstName"));
        this.brideLastNameColumn.setCellValueFactory(new PropertyValueFactory<Bride, String>("lastName"));
        this.marriageDateColumn.setCellValueFactory(new PropertyValueFactory<Marriage, LocalDate>("marriageDate"));
    }

在里面 initialize 方法,我正在尝试设置 CellValueFactory 对于每个表列,我可以显示 Marriage 对象在我的tableview中。
然而,婚姻对象由另一个类型的对象新郎和新娘组成,我试图从中展示一些价值观。

public class Marriage {
    private Groom groom;
    private Bride bride;
    private LocalDate marriageDate;
}

public class Groom:
{
    private String firstName;
    private String lastName;
}

public class Bride:
{
    private String firstName;
    private String lastName;
}

我得到的例外:

java.lang.IllegalStateException: Cannot read from unreadable property firstName

如何设置 CellValueFactory 或编辑 TableColumn 的通用参数,以便显示嵌套对象的属性?

fhity93d

fhity93d1#

一种选择是使用自定义单元格实现,它知道如何显示所需的单元格数据 GroomBride . 例如:

TableColumn<Marriage, Groom> groomCol = ...;
groomCol.setCellValueFactory(new PropertyValueFactory<>("groom"));
groomCol.setCellFactory(tc -> new TableCell<>() {

  @Override
  protected void updateItem(Groom item, boolean empty) {
    super.updateItem(item, empty); // must be called
    if (empty || item == null) {
      setText(null);
    } else {
      // replace with desired format
      setText(item.getFirstName() + " " + item.getLastName());
    }
  }
});

请注意 TableColumn 必须与的类型参数匹配 TableView ( Marriage 在这种情况下)。
顺便问一下,你真的需要两者都有吗 GroomBride 上课?它们似乎具有相同的信息,并且可能组合成一个单一的 Person 班级。
另一方面,你应该避免 PropertyValueFactory 如果可以的话。它是在lambda表达式出现之前的时代设计的,目的是使代码更加简洁。但是对于lambda表达式,您可以执行相同的操作,但是要使用编译时安全性(并且要避免反射)。不过请注意,如果您将模型的属性公开为javafx属性,那么这种方法效果最好。例如:

// model class
public class Marriage {
  private final ObjectProperty<Groom> groom = new SimpleObjectProperty<>(this, "groom");
  public final void setGroom(Groom groom) { this.groom.set(groom); }
  public final Groom getGroom() { return groom.get(); }
  public final ObjectProperty<Groom> groomProperty() { return groom; }

  // other properties...
}
// table column configuration
TableColumn<Marriage, Groom> groomCol = ...;
groomCol.setCellValueFactory(data -> data.getValue().groomProperty());
groomCol.setCellFactory( ... );

相关问题