需要将DefaultTableModel转换为表视图JavaFX的帮助吗

需要将DefaultTableModel转换为表视图JavaFX的帮助吗,java,sql,swing,javafx,Java,Sql,Swing,Javafx,经过一个又一个小时的努力,我的项目快到截止日期了,但我还没有找到解决我这个相当容易的问题的办法。我需要用SQL查询中的数据填充tableview,但即使复制粘贴在线示例,也无法使其工作。。。我需要与以下代码相同的结果 public DefaultTableModel buildTableModel() { ResultSetMetaData metaData; try (Connection conn = DriverManager.getConnection(M

经过一个又一个小时的努力,我的项目快到截止日期了,但我还没有找到解决我这个相当容易的问题的办法。我需要用SQL查询中的数据填充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();
    }
public DefaultTableModel buildTableModel(){
结果元数据;
try(Connection conn=DriverManager.getConnection(MapperConfig.JDBC_URL)){
PreparedStatement queryOpgeslagenGames=conn.prepareStatement(“”);
结果集rs=queryOpgeslagenGames.executeQuery(“选择spellen.spelID,spellen.spelNaam为'Naam van Spel',group_concat(Naam分隔符','))为spellen上Speller的“Deelnemende Speller”,通过spellen.spelID=Spelles.speller按spellen.spelID分组”);
元数据=rs.getMetaData();
//列名
向量列名称=新向量();
int columnCount=metaData.getColumnCount();

for(int column=1;columnJavaFX
TableView
s基于一个模型,其中每一行由一个对象表示。每一列都有一个关联函数(cellValueFactory
),该函数将一行的对象映射到该列相应单元格中显示的值

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

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);
    }
}
公共类游戏{
//也许是一个完整的属性?
私有最终StringProperty id=新的SimpleStringProperty();
私有最终StringProperty saveFileName=新SimpleStringProperty();
private final ListProperty playerNames=新的SimpleListProperty(FXCollections.observableArrayList());
公共游戏(字符串id、字符串保存文件名、字符串…玩家名称){
setId(id);
设置保存文件名(保存文件名);
playerNames.get().setAll(playerNames);
}
公共属性idProperty(){
返回id;
}
公共最终字符串getId(){
返回idProperty().get();
}
公共最终无效集合id(字符串id){
idProperty().set(id);
}
//同样,对于saveFileName。。。
public ListProperty playerNamesProperty(){
返回游戏时间;
}
公共最终观察者getPlayerNames(){
返回playerNameProperty().get();
}
公共最终无效集合玩家名称(可观察列表玩家名称){
playerNameProperty().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();
}
公共可观察列表buildTableModel(){
try(Connection conn=DriverManager.getConnection(MapperConfig.JDBC_URL)){
PreparedStatement queryOpgeslagenGames=conn.prepareStatement(“”);
结果集rs=queryOpgeslagenGames.executeQuery(“选择spellen.spelID,spellen.spelNaam为'Naam van Spel',group_concat(Naam分隔符','))为spellen上Speller的“Deelnemende Speller”,通过spellen.spelID=Spelles.speller按spellen.spelID分组”);
//表中的数据
ObservableList games=FXCollections.observableArrayList();
while(rs.next()){
字符串id=rs.get(1);
字符串saveFileName=rs.get(2);
字符串[]playerNames=rs.get(3).split(“,”);
游戏=新游戏(id、保存文件名、玩家姓名);
games.add(游戏);
}
返回游戏;
}catch(SQLException-ex){
用于(可丢弃的t:ex){
t、 printStackTrace();
}
}
返回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);
TableView table=newtableview();
TableColumn idColumn=新的TableColumn(“ID”);
idColumn.setCellValueFactory(cellData->cellData.getValue().idProperty());
TableColumn saveFileNameColumn=新建TableColumn(“保存文件名”);
saveFileNameColumn.setCellValueFactory(cellData->cellData.getValue().saveFileNameProperty());
TableColumn playerNamesColumn=新的TableColumn(“玩家名称”);
PlayerNameColumn.setCellValueFactory(cellData->callData.getValue().PlayerNameProperty());
setItems(buildTableModel());
table.getColumns().addAll(idColumn、saveFileNameColumn、PlayerNameColumn);
您还可以使用以下方法改进“播放器名称”列中的渲染

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));
        }
    }
});
playerNameColumn.setCellFactory(col->newTableCell()){
@凌驾
受保护的void updateItem(可观察列表playerNames,布尔值为空){
super.updateItem(playerNames,空);
if(空){
setText(空);
}否则{
setText(String.join(“,”,playername));
}
}
});
或者,对于更复杂的显示:

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);
        }
    }
});
playerNameColumn.setCellFactory(col->newTableCell()){
私有最终ListView ListView=新建ListView();
@凌驾
受保护的void updateItem(可观察列表playerNames,布尔值为空){
super.updateItem(playerNames,空);
if(空){
设置图形(空);
}否则{
listView.setItems(播放名称);
setGraphic(listView);
}
}
});

从SQL语句中,您似乎知道将有多少列,以及这些列中的数据代表什么。这是否正确?如果正确,您能否在问题中明确地包含这些信息?(顺便说一句,我不认为在这个论坛上为答案付费是可以接受的。这当然不符合网站的精神。)@James_D补充道:表中始终有3个列,第一个是游戏ID,第二个是游戏保存文件名,第三个是游戏中人物的名字集合。你有没有参考过这篇文章?假设你可以从这篇文章中找到更好的解决方案。另外,你是每个学生都需要的英雄,但没有人值得,你有吗