【问题标题】:TableView created via fxml not populating通过 fxml 创建的 TableView 未填充
【发布时间】:2016-11-30 14:10:23
【问题描述】:

我正在尝试将 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 制作的。当我尝试集成上面的示例时,表格没有填充,因此我创建了以下最小示例来演示我的问题:

[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:

但它看起来像这样:

【问题讨论】:

    标签: javafx fxml


    【解决方案1】:

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

    不过,您永远不会将此表添加到场景中...

    假设TransitionRow 类包含适合PropertyValueFactory 工作的方法,以下代码应该可以工作。

    @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);
    }
    

    【讨论】:

    • 我按照您的建议编辑了“初始化”,它没有任何区别吗?另外,我不明白您所说的“添加到场景中”是什么意思。当然 tableview 是通过 SceneBuilder/fxml 创建的,我只想对其进行配置和数据?
    • 另外我假设 TransitionRow 有正确的方法,因为它在第一个代码 sn-p: FxTableViewExample1 中与 PropertyValueFactory 完美配合
    • @Ralph 我刚刚用我的修改测试了代码,它可以工作......一定有什么问题你没有发布任何关于......的信息......通过“添加到场景” 将代码添加到作为/成为场景根的后代的父级或添加到该根本身,当您覆盖字段的值时,您不会这样做。
    • 抱歉,当我从您的答案中复制和粘贴时,我错过了删除 col = new TableColumn 语句之一。已经纠正了我的粗心,现在它可以完美运行了 :-) 感谢您的额外解释。
    猜你喜欢
    • 1970-01-01
    • 2013-06-28
    • 2016-02-16
    • 2014-10-08
    • 2018-10-14
    • 2014-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多