TableViewセルの扱い方
面倒で不安定なフィールド指定
TableViewに指定されるColumnのフィールドは文字列で指定される例が多い。その文字列から適切なフィールドとして使用できる「メソッド」が勝手に探し出される。 以下の例では、
- "email"はemailProperty()メソッドが
- "name"はgetName()メソッドが
- "address"はaddressProperty()メソッドが
探し出される。通常は「フィールド名 + Property」というObservableValueが返されるメソッドが探し出されるが、なければ「get + 頭大文字フィールド名」というゲッターメソッドが採用されるようだ。 しかしこれには問題がある。
- 列に指定するフィールド名が間違っていた場合に何もエラーが出ない、セルが空白になるだけ。
- メソッド側の名称が間違っていた場合も同じ。
TableViewに表示した後でセル内容を変更したい場合には、必ずObservableValueにする必要がある。つまり、setName()メソッドでnameデータを変更しても(特殊な方法以外では)それをテーブルに反映する方法はない。
- ともあれ、文字列による結合なので、Obfuscatorにかけた場合には全く動作しなくなる。
- 行のフィールドが不必要なものでいっぱいになる。
import javafx.application.*; import javafx.beans.property.*; import javafx.scene.*; import javafx.scene.control.*; import javafx.scene.control.cell.*; import javafx.stage.*; public class CumbersomeFields extends Application { public static class Row { Row(String email, String name, String address) { this.emailWrapper.set(email); this.name = name; this.addressProperty.set(address); } private ReadOnlyStringWrapper emailWrapper = new ReadOnlyStringWrapper(); public ReadOnlyStringProperty emailProperty() { return emailWrapper.getReadOnlyProperty(); } private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public SimpleStringProperty addressProperty = new SimpleStringProperty(); public SimpleStringProperty addressProperty() { return addressProperty; } } @SuppressWarnings("unchecked") @Override public void start(Stage stage) throws Exception { TableView<Row>tableView= new TableView<>(); tableView.getColumns().addAll( new Column<Row, String>("EMAIL", "email").col, new Column<Row, String>("NAME", "name").col, new Column<Row, String>("ADDRESS", "address").col ); tableView.getItems().addAll( new Row("email1", "name1", "address1"), new Row("email2", "name2", "address") ); stage.setScene(new Scene(tableView)); stage.show(); } static class Column<E, T> { TableColumn<E, T>col; Column(String title, String field) { col = new TableColumn<E, T>(title); col.setCellValueFactory(new PropertyValueFactory<E, T>(field)); } } public static void main(String[] args) throws Exception { launch(args); } }