添加rowfactory

时间:2017-12-05 22:15:10

标签: java javafx fxml factory-pattern netbeans-platform

我正在尝试设置一个显示Pet对象列表的netbeans / javafx程序,并为每一行提供一个onclick监听器。

我在fxml中有以下内容:

MyTables.fxml

<VBox alignment="CENTER" layoutX="11.0" layoutY="12.0" prefWidth="345.0">
    <children>
        <TableView id="Table1" fx:id="Table1" styleClass="mytable"/>
        <TableView id="Table2" fx:id="Table2" styleClass="mytable"/>
        <TableView id="Table3" fx:id="Table3" styleClass="mytable"/>
        <TableView id="Table4" fx:id="Table4" styleClass="mytable"/>
    </children>
</VBox>

我正在使用netbeans,所以我为视图设置了一个topComponent,它加载了FXML,后者又加载了一个控制器类。

在我的控制器类中,我有以下代码来向表中添加内容。目的是使每个表有3行,对应于所包含的Pet对象的ID,Name和Owner。

MyTablesController.java

public class MyTablesController implements Initializable {

    @FXML
    private TableView<Pet> Table1;
    @FXML
    private TableView<Pet> Table2;
    @FXML
    private TableView<Pet> Table3;
    @FXML
    private TableView<Pet> Table4;

    private TableView<Pet>[] allTables;

    public MyTablesController() {
        allTables = new TableView[4];
        allTables[0] = Table1;
        allTables[1] = Table2;
        allTables[2] = Table3;
        allTables[3] = Table4;
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        for(TableView<Pet> table : allTables) {
            table.getColumns().add(createCol("ID", Pet::idProperty, 100));
            table.getColumns().add(createCol("Name", Pet::nameProperty, 140));
            table.getColumns().add(createCol("Owner", Pet::ownerProperty, 100));
            table.getItems().addAll(
                    new Pet("1234", "spot", "joe"),
                    new Pet("5432", "snowball", "bill"),
                    new Pet("7612", "snoopy", "frank")
            );
        }

        setupTableRowDragEvents();
    }

    private TableColumn<Pet, String> createCol(String title, 
            Function<Pet, ObservableValue<String>> mapper, double size) {

        TableColumn<Pet, String> col = new TableColumn<>(title);
        col.setCellValueFactory(cellData -> mapper.apply(cellData.getValue()));
        col.setPrefWidth(size);
        return col ;
    }

    private void setupTableRowDragEvents() {
        for (TableView<Pet> table : allTables) {
            table.setRowFactory(tv -> {
                TableRow<Pet> row = new TableRow<>();
                row.setOnMouseClicked(event -> {
                    System.out.println("I CLICKED ON " + row.getItem().getName()");
                });
                return row;
            });
        }
    }
}

最后,这是Pet对象:

Pet.java

public final class Pet {

    public final StringProperty id = new SimpleStringProperty(this, "id");
    public final StringProperty name = new SimpleStringProperty(this, "name");
    public final StringProperty owner = new SimpleStringProperty(this, "owner");

    public Pet() {}

    public Pet(String id, String name, String owner) {
        this.id.set(id);
        this.name.set(name);
        this.owner.set(owner);
    }

    public String getId() {
        return id.get();
    }

    public void setId(String id) {
        this.id.set(id);
    }

    public StringProperty idProperty() {
        return id;
    }

    public String getName() {
        return name.get();
    }

    public void setName(String name) {
        this.name.set(name);
    }

    public StringProperty nameProperty() {
        return name;
    }

    public String getOwner() {
        return owner.get();
    }

    public void setOwner(String owner) {
        this.owner.set(owner);
    }

    public StringProperty ownerProperty() {
        return owner;
    }
}

这是我的问题。

如果我将MyTablesController.initialize留空,则4个图表显示正常。只有当我添加其余的代码(setCols调用和setupTableRowDragEvents()调用)时......

如果存在initialize()中的任何一个或两个,则不显示图形。除了窗口完全是空的并且图形没有显示之外,我没有得到任何错误消息或奇怪的行为。

我的代码基于sort tableview with drag and drop (rows)。与此相比,我无法弄清楚我在哪里搞砸了。这个答案是错的,没有人费心去检查吗?

我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

在填充数组时,表视图引用都是null,因此您使用空引用填充数组。然后,当您遍历数组时,第一次调用table.getColumns()时将获得空指针异常。将代码从控制器构造函数移动到initialize()的开头:

public class MyTablesController implements Initializable {

    @FXML
    private TableView<Pet> Table1;
    @FXML
    private TableView<Pet> Table2;
    @FXML
    private TableView<Pet> Table3;
    @FXML
    private TableView<Pet> Table4;

    private TableView<Pet>[] allTables;

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        allTables = new TableView[4];
        allTables[0] = Table1;
        allTables[1] = Table2;
        allTables[2] = Table3;
        allTables[3] = Table4;

        for(TableView<Pet> table : allTables) {
            table.getColumns().add(createCol("ID", Pet::idProperty, 100));
            table.getColumns().add(createCol("Name", Pet::nameProperty, 140));
            table.getColumns().add(createCol("Owner", Pet::ownerProperty, 100));
            table.getItems().addAll(
                    new Pet("1234", "spot", "joe"),
                    new Pet("5432", "snowball", "bill"),
                    new Pet("7612", "snoopy", "frank")
            );
        }

        setupTableRowDragEvents();
    }

    // ...

}