需要帮助将DefaultTableModel转换为Table View JavaFX

时间:2017-05-11 23:52:54

标签: java sql swing javafx

经过数小时和数小时的尝试,我已经接近我的项目截止日期,但仍然无法解决我相当容易的问题。我需要使用SQL Query中的数据填充tableview,但即使我复制粘贴在线示例,我也无法使其工作......我需要与以下代码相同的结果

public DefaultTableModel buildTableModel() {
        ResultSetMetaData metaData;
        try (Connection conn = DriverManager.getConnection(MapperConfig.JDBC_URL)) {
            PreparedStatement queryOpgeslagenGames = conn.prepareStatement("");
            ResultSet rs = queryOpgeslagenGames.executeQuery("SELECT spellen.spelID, spellen.spelNaam AS 'Naam van Spel', group_concat( naam separator ', ') AS 'Deelnemende spelers' FROM spellen RIGHT JOIN spelers ON spellen.spelID =     spelers.spelID GROUP BY spellen.spelID");
            metaData = rs.getMetaData();
            // names of columns
            Vector<String> columnNames = new Vector<String>();
            int columnCount = metaData.getColumnCount();
            for (int column = 1; column <= columnCount; column++) {
                columnNames.add(metaData.getColumnName(column));
            }

            // data of the table
            Vector<Vector<Object>> data = new Vector<Vector<Object>>();
            while (rs.next()) {
                Vector<Object> vector = new Vector<Object>();
                for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
                    vector.add(rs.getObject(columnIndex));
                }
                data.add(vector);
            }
        return new DefaultTableModel(data, columnNames);
        } catch (SQLException ex) {
            for (Throwable t : ex) {
                t.printStackTrace();
            }
        }
        return new DefaultTableModel();
    }

但由于我需要在JavaFX中使用它,我无法使用Jtable并需要使用表视图。有人可以为我转换代码吗?或者告诉我如何使用DefaultTableModel制作表格视图?

该表总是有3个列,首先是gameID,第二个是游戏保存文件名,第三个是游戏中人员的名字集合。

1 个答案:

答案 0 :(得分:1)

JavaFX TableView基于一个模型,其中每一行由一个对象表示。每列都有一个关联的函数(cellValueFactory),它将行的对象映射到要在该列的相应单元格中显示的值。

因此,您应该首先定义一个表示每行中项目的类。最好使用JavaFX properties pattern执行此操作,这将允许表格轻松绑定到此类实例中的数据。

public class Game {

    // maybe an IntegerProperty?
    private final StringProperty id = new SimpleStringProperty();
    private final StringProperty saveFileName = new SimpleStringProperty();
    private final ListProperty<String> playerNames = new SimpleListProperty<>(FXCollections.observableArrayList()); 

    public Game(String id, String saveFileName, String... playerNames) {
        setId(id);
        setSaveFileName(saveFileName);
        playerNames.get().setAll(playerNames);
    }

    public StringProperty idProperty() {
        return id ;
    }

    public final String getId() {
        return idProperty().get();
    }

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

    // similarly for saveFileName...

    public ListProperty<String> playerNamesProperty() {
        return playerNames ;
    }

    public final ObservableList<String> getPlayerNames() {
        return playerNamesProperty().get();
    }

    public final void setPlayerNames(ObservableList<String> playerNames) {
        playerNamesProperty().set(playerNames);
    }
}

现在您的数据访问器方法应如下所示:

public ObservableList<Game> buildTableModel() {

    try (Connection conn = DriverManager.getConnection(MapperConfig.JDBC_URL)) {
        PreparedStatement queryOpgeslagenGames = conn.prepareStatement("");
        ResultSet rs = queryOpgeslagenGames.executeQuery("SELECT spellen.spelID, spellen.spelNaam AS 'Naam van Spel', group_concat( naam separator ', ') AS 'Deelnemende spelers' FROM spellen RIGHT JOIN spelers ON spellen.spelID =     spelers.spelID GROUP BY spellen.spelID");
        // data of the table
        ObservableList<Game> games = FXCollections.observableArrayList();
        while (rs.next()) {
            String id = rs.get(1);
            String saveFileName = rs.get(2);
            String[] playerNames = rs.get(3).split(", ");
            Game game = new Game(id, saveFileName, playerNames);
            games.add(game);
        }
        return games ;
    } catch (SQLException ex) {
        for (Throwable t : ex) {
            t.printStackTrace();
        }
    }
    return FXCollections.observableArrayList();
}

最后你用

设置了表格
TableView<Game> table = new TableView<>();
TableColumn<Game, String> idColumn = new TableColumn<>("ID");
idColumn.setCellValueFactory(cellData -> cellData.getValue().idProperty());
TableColumn<Game, String> saveFileNameColumn = new TableColumn<>("Save file name");
saveFileNameColumn.setCellValueFactory(cellData -> cellData.getValue().saveFileNameProperty());
TableColumn<Game, ObservableList<String>> playerNamesColumn = new TableColumn<>("Player names");
playerNamesColumn.setCellValueFactory(cellData -> callData.getValue().playerNamesProperty());

table.setItems(buildTableModel());

table.getColumns().addAll(idColumn, saveFileNameColumn, playerNamesColumn);

您还可以使用类似

的内容改进播放器名称列中的渲染
playerNamesColumn.setCellFactory(col -> new TableCell<Game, ObservableList<String>>() {
    @Override
    protected void updateItem(ObservableList<String> playerNames, boolean empty) {
        super.updateItem(playerNames, empty);
        if (empty) {
            setText(null);
        } else {
            setText(String.join(", ", playerNames));
        }
    }
});

或者,对于更复杂的显示器:

playerNamesColumn.setCellFactory(col -> new TableCell<Game, ObservableList<String>>() {

    private final ListView<String> listView = new ListView<>();

    @Override
    protected void updateItem(ObservableList<String> playerNames, boolean empty) {
        super.updateItem(playerNames, empty);
        if (empty) {
            setGraphic(null);
        } else {
            listView.setItems(playerNames);
            setGraphic(listView);
        }
    }
});