0

I want to display data from a database within the tableview of the GUI.

I have tried may different ways to no avail. The code runs without errors yet still nothing shows in the table view.

Can you please help clarify my understanding on how to do this.


public class LeaderBoardView implements Initializable {

    @FXML private TableColumn<LeaderBoardData, String> colUsername;
    @FXML private TableColumn<LeaderBoardData, Integer> colWins;
    @FXML private TableColumn<LeaderBoardData, Integer> colWinPercentage;
    @FXML private TableView<LeaderBoardData> tableLeaderboard;
    private ObservableList<LeaderBoardData> data;


    @Override
    public void initialize(URL location, ResourceBundle resources) {

        colUsername.setCellValueFactory(
                new PropertyValueFactory<LeaderBoardData,String>("username"));
        colWins.setCellValueFactory(
                new PropertyValueFactory<LeaderBoardData, Integer>("wins"));
        colWinPercentage.setCellValueFactory(
                new PropertyValueFactory<LeaderBoardData, Integer>("winPercentage"));

        buildLeaderBoardData();

    }


    public void buildLeaderBoardData() {
        data = FXCollections.observableArrayList();
        try {
            ResultSet rs = UserDB.getLeaderBoardData();

            while(rs.next()){
                LeaderBoardData cm = new LeaderBoardData();

                cm.username.set(rs.getString("username"));
                cm.wins.set(rs.getInt("wins"));
                cm.winPercentage.set(rs.getInt("winPercentage"));
                data.add(cm);

                //System.out.println(data.get());
            }
            tableLeaderboard.setItems(data);

        } catch(Exception e) {
            e.printStackTrace();
            System.out.println("Error on Building Data");
        }
    }


public class LeaderBoardData {

    public SimpleStringProperty username;
    public SimpleIntegerProperty wins;
    public SimpleIntegerProperty winPercentage;


//    public UserData(String username, int wins, int winPercentage) {
//        this.username = new SimpleStringProperty(username);
//        this.wins = new SimpleIntegerProperty(wins);
//        this.winPercentage = new SimpleIntegerProperty(winPercentage);
//    }


    public String getUsername() {
        return username.get();
    }



    public Integer getUserWins() {
        return wins.get();
    }



    public Integer getWinPercent() {
        return winPercentage.get();
    }



}

Expected result - to get the table view to display a Leader Board of Users, Wins, Win Percentage

Javasaurusrex
  • 123
  • 1
  • 7

1 Answers1

2

Each Java bean property name is derived from the name of the corresponding get-method, by removing get and decapitalizing the rest of the method name. Fields are not considered in any way, only methods.

Your LeaderBoardData class has these get-methods, which correspond to the following properties:

  • getUsername() → property "username"
  • getUserWins() → property "userWins"
  • getWinPercent() → property "winPercent"

You must use the above property names exactly:

colUsername.setCellValueFactory(
        new PropertyValueFactory<LeaderBoardData,String>("username"));
colWins.setCellValueFactory(
        new PropertyValueFactory<LeaderBoardData, Integer>("userWins"));
colWinPercentage.setCellValueFactory(
        new PropertyValueFactory<LeaderBoardData, Integer>("winPercent"));

A better approach is to avoid reflection entirely. Reflection errors like yours cannot be caught by a compiler, but code that calls methods directly is checked by the compiler.

First, you need to make your LeaderBoardData class provide properties in the standard manner that most JavaFX classes provide theirs: a property method and a get-method (and if the property is writable, a set-method). The javafx.scene.Node documentation illustrates this.

In your case, your class would look like this:

public class LeaderBoardData {

    private StringProperty username = new SimpleStringProperty();
    private IntegerProperty wins = new SimpleIntegerProperty();
    private IntegerProperty winPercentage = new SimpleIntegerProperty();

    public StringProperty usernameProperty() {
        return username;
    }

    public String getUsername() {
        return username.get();
    }

    public void setUsername(String name) {
        this.username.set(name);
    }

    public IntegerProperty userWinsProperty() {
        return wins;
    }

    public int getUserWins() {
        return wins.get();
    }

    public void setUserWins(int wins) {
        this.wins.set(wins);
    }

    public IntegerProperty winPercentProperty() {
        return winPercentage;
    }

    public int getWinPercent() {
        return winPercentage.get();
    }

    public void setWinPercent(int percent) {
        this.winPercentage.set(percent);
    }
}

Now, your cell value factories can use explicit method calls:

colUsername.setCellValueFactory(f -> f.getValue().usernameProperty());
colWins.setCellValueFactory(f -> f.getValue().userWinsProperty());
colWinPercentage.setCellValueFactory(f -> f.getValue().winPercentProperty());
VGR
  • 40,506
  • 4
  • 48
  • 63