通过 fxml 创建的 TableView 未填充

TableView created via fxml not populating

我正在尝试将 TableView 控件添加到预先存在的应用程序中。我正在尝试复制以下示例代码(运行完美):

public class FxTableViewExample1 extends Application {

    private TableView<TransitionRow> outputTable;
    private ObservableList<TransitionRow> data;

    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Table View Example 1");

        // Table view, data, columns and properties
        outputTable = new TableView<TransitionRow>();
        data = getInitialTableData();
        outputTable.setItems(data);

        TableColumn col1 = new TableColumn("Harland");
        col1.setCellValueFactory(new PropertyValueFactory<TransitionRow, Double>("scaleY"));

        TableColumn col2 = new TableColumn("Gradstein");
        col2.setCellValueFactory(new PropertyValueFactory<TransitionRow, Double>("gradsteinAge"));

        TableColumn col3 = new TableColumn("Label");
        col3.setCellValueFactory(new PropertyValueFactory<TransitionRow, String>("oldName"));

        outputTable.getColumns().setAll(col1, col2, col3);
        outputTable.setPrefWidth(450);
        outputTable.setPrefHeight(300);

        // Vbox
        VBox vbox = new VBox(20);
        vbox.setPadding(new Insets(25, 25, 25, 25));;
        vbox.getChildren().addAll(outputTable);

        // Scene
        Scene scene = new Scene(vbox, 500, 475); // w x h
        primaryStage.setScene(scene);
        primaryStage.show();

        // Select the first row
        outputTable.getSelectionModel().select(0);
        TransitionRow tr = outputTable.getSelectionModel().getSelectedItem();
        System.out.println(tr);
    }

    private ObservableList<TransitionRow> getInitialTableData() {
        List<TransitionRow> list = new ArrayList<>();

        TransitionRow tr1 = new TransitionRow();
        tr1.setScaleY((Double) 124.567d);
        tr1.setGradsteinAge((Double) 130.001d);
        tr1.setOldName("Stuff");

        TransitionRow tr2 = new TransitionRow();
        tr2.setScaleY((Double) 456.546d);
        tr2.setGradsteinAge((Double) 123.768d);
        tr2.setOldName("Other stuff");

        list.add(tr1);
        list.add(tr2);

        ObservableList<TransitionRow> data = FXCollections.observableList(list);
        return data;
    }
}

我的应用是通过带有单独控制器的 SceneBuilder 创建的 类。当我尝试集成上面的示例时,table 没有填充,所以我创建了以下最小示例来演示我的问题:

[Test1Run.java]

public class Test1Run extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("Test1.fxml"));
        stage.setTitle("Test1");
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}

[Test1.fxml]

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.60" fx:controller="experimental.tableview.Test1Controller">
    <TableView fx:id="outputTable" layoutX="14.0" layoutY="14.0" prefHeight="371.0" prefWidth="569.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="17.0">
        <columns>
            <TableColumn fx:id="col1" prefWidth="75.0" text="C1" />
            <TableColumn fx:id="col2" prefWidth="75.0" text="C2" />
            <TableColumn fx:id="col3" prefWidth="75.0" text="C3" />
        </columns>
    </TableView>
</AnchorPane>

[Test1Controller.java]

public class Test1Controller implements Initializable {
    @FXML private TableView<TransitionRow> outputTable;
    @FXML private TableColumn<TransitionRow, Double> col1;
    @FXML private TableColumn<TransitionRow, Double> col2;
    @FXML private TableColumn<TransitionRow, String> col3;

    private ObservableList<TransitionRow> data;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        outputTable = new TableView<TransitionRow>();

        col1 = new TableColumn<TransitionRow,Double>("Harland");
        col1.setCellValueFactory(new PropertyValueFactory<TransitionRow, Double>("scaleY"));

        col2 = new TableColumn<TransitionRow,Double>("Gradstein");
        col2.setCellValueFactory(new PropertyValueFactory<TransitionRow, Double>("gradsteinAge"));

        col3 = new TableColumn<TransitionRow,String>("Label");
        col3.setCellValueFactory(new PropertyValueFactory<TransitionRow, String>("oldName"));

        // This line should cause the column names on the GUI to change. They don't.
        outputTable.getColumns().addAll(col1, col2, col3);

        data = getInitialTableData();

        // This line should cause rows of data to appear on the TableView. It doesn't.
        outputTable.setItems(data);

    }    

    private ObservableList<TransitionRow> getInitialTableData() {
        List<TransitionRow> list = new ArrayList<>();

        TransitionRow tr1 = new TransitionRow();
        tr1.setScaleY((Double) 124.567d);
        tr1.setGradsteinAge((Double) 130.001d);
        tr1.setOldName("Stuff");

        TransitionRow tr2 = new TransitionRow();
        tr2.setScaleY((Double) 456.546d);
        tr2.setGradsteinAge((Double) 123.768d);
        tr2.setOldName("Other stuff");

        list.add(tr1);
        list.add(tr2);

        ObservableList<TransitionRow> results = FXCollections.observableList(list);
        return results;
    }
}

我希望它看起来像 FxTableViewExample1:

但它看起来像这样:

initialize 中,您使用在第一条语句中创建的新 TableView

虽然你从未将此 table 添加到场景中...

假设 TransitionRow class 包含用于 PropertyValueFactory 的 suitable 方法,以下代码应该可以工作。

@Override
public void initialize(URL url, ResourceBundle rb) {
    col1.setText("Harland");
    col1.setCellValueFactory(new PropertyValueFactory<TransitionRow, Double>("scaleY"));

    col2.setText("Gradstein");
    col2.setCellValueFactory(new PropertyValueFactory<TransitionRow, Double>("gradsteinAge"));

    col3.setText("Label");
    col3.setCellValueFactory(new PropertyValueFactory<TransitionRow, String>("oldName"));

    data = getInitialTableData();

    outputTable.setItems(data);
}