经过数小时和数小时的尝试,我已经接近我的项目截止日期,但仍然无法解决我相当容易的问题。我需要使用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,第二个是游戏保存文件名,第三个是游戏中人员的名字集合。
答案 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);
}
}
});