I am creating a scoreboard with javafx.
My program has a table, with one column which is game id. When you press new game you can add up to 10 players. Type in the players names and press the button to add players to the table columns. I have provided pics below so you can have a clearer understanding.
After players added to columns
Here is where I'm stuck. I need to add scores per game on the rows. Since I'm generating a custom number (2-10) of columns depending on the number of players. I can't use this code because I don't know how many parameter is needed for score constructor in Score Class.
Is there a way to create 3 int parameter in the score class if there are 3 players added? Or could I approach this in a different way? Another option maybe will be to add random numbers below then dynamically editing the rows to the real score, but then again the program doesn't know how many columns there are so this will be hard as well.
public ObservableList<Score> getScore() {
ObservableList<Score> scores= FXCollections.observableArrayList();
scores.add(new Score(10,12,13,11,15,90));
scores.add(new Score(100,10,29,29));
return scores;
}
Example of what I'm think how it should look:
Game Nr:|Bill Gates | Steve Jobs |
1 | 80 | 10 |
2 | 6 | 75 |
PS: Is there a way to sum the column and show the total score. I want the sum to be on the last row so even if I add a new row with scores the sum will appear below that row.
Codes Used to add players from textfield to column:
TableColumn<Player, String> p1 = new TableColumn<>(player1.getText());
TableColumn<Player, String> p2 = new TableColumn<>(player2.getText());
TableColumn<Player, String> p3 = new TableColumn<>(player3.getText());
table.getColumns().addAll(p1, p2, p3);
You can create a game class which has a game number (fixed) and represents the scores as a map from players to values:
public class Game {
private final int gameNumber ;
private final ObservableMap<String, Integer> scores
= FXCollections.observableHashMap();
public Game(int gameNumber) {
this.gameNumber = gameNumber ;
}
public ObservableMap<String, Integer> getScores() {
return scores ;
}
public int getGameNumber() {
return gameNumber ;
}
}
If I understand the requirements correctly, when the user enters new players, you want to reset the table, which you can do with the method below:
private TableView<Game> scoreTable ;
// ...
private void resetTable(List<String> players) {
scoreTable.getColumns().clear();
scoreTable.getItems().clear();
TableColumn<Game, Integer> gameNumCol = new TableColumn<>("Game");
gameNumCol.setCellValueFactory(cellData -> new ObservableValueBase<Integer>() {
@Override
public Integer getValue() {
return cellData.getValue().getGameNumber();
}
});
scoreTable.getColumns().add(gameNumCol);
for (String player : players) {
TableColumn<Game, Integer> col = new TableColumn<>(player);
col.setCellValueFactory(cellData -> {
Game game = cellData.getValue();
IntegerBinding score = Bindings.createIntegerBinding(() ->
game.getScores().getOrDefault(player, 0),
game.getScores());
return score.asObject() ;
});
// if you need editing:
col.setOnEditCommit(e -> {
Game game = e.getRowValue();
Integer newScore = e.getNewValue();
game.getScores().put(player, newScore);
});
scoreTable.getColumns().add(col);
}
}
Then you can just add new Game
s to the table's items list, and they will default to zero scores for each player. You can set scores with
game.getScores().put(player, score);
SSCCE at https://gist.github.com/james-d/aa51204a2e7ed16d75b7