需要将DefaultTableModel转换为表视图JavaFX的帮助吗
经过一个又一个小时的努力,我的项目快到截止日期了,但我还没有找到解决我这个相当容易的问题的办法。我需要用SQL查询中的数据填充tableview,但即使复制粘贴在线示例,也无法使其工作。。。我需要与以下代码相同的结果需要将DefaultTableModel转换为表视图JavaFX的帮助吗,java,sql,swing,javafx,Java,Sql,Swing,Javafx,经过一个又一个小时的努力,我的项目快到截止日期了,但我还没有找到解决我这个相当容易的问题的办法。我需要用SQL查询中的数据填充tableview,但即使复制粘贴在线示例,也无法使其工作。。。我需要与以下代码相同的结果 public DefaultTableModel buildTableModel() { ResultSetMetaData metaData; try (Connection conn = DriverManager.getConnection(M
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;columnJavaFXTableView
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,第二个是游戏保存文件名,第三个是游戏中人物的名字集合。你有没有参考过这篇文章?假设你可以从这篇文章中找到更好的解决方案。另外,你是每个学生都需要的英雄,但没有人值得,你有吗