0

I have a TableView in JavaFX that I want to fill with some JSON data.

The JSON that I receive from the server looks like this:

{"mirelradoi":10,"test":6, "bob":3}

But I'm having a hard time understanding how to use this TableView. I created the TableView in SceneBuilder already (with its coresponding columns) so in my code I'm not initializing it anymore. (I don't think I still need it - I might be wrong, I'm a complete beginner :) )

And here's the way I'm adding that JSON in the tableview:

            tabelClasament.setItems(FXCollections.observableArrayList(receivedJSON.get("clasament")));

Where tableClasament is the TableView I'm talking about, and receivedJSON.get("clasament") gets me the data that I've shown above.

But for some reason, I get this: click

so I don't get "No content in the table" like not having data, but it doesn't show either.

How can I import that JSON into this table? The only thing in my code about the table is that line and the definition of tableClasament as TableView.

Thanks.

Octavian Niculescu
  • 1,177
  • 1
  • 3
  • 24
  • 2
    I would be best to create a data model class to hold the info from the JSON. Then you need to set the `CellValueFactory` for each column in order for them to display the information you want. Provide a [mcve] of what you have so far if you want detailed help. – Zephyr Jan 30 '22 at 21:25
  • work through a tutorial about how to use tableview, apply what you learned, when stuck come back with a [mcve] demonstrating what's wrong – kleopatra Jan 30 '22 at 23:50
  • To map Json to and from Java objects use a library such as [Jackson](https://www.baeldung.com/jackson-object-mapper-tutorial). – jewelsea Jan 31 '22 at 08:40

1 Answers1

1

When adding data to a TableView, you must also specify how each column should display the given data (ie: the TableView won't magically know which column corresponds to each field or property in your JSON data).

It is recommended to create a data model class to represent the data in your JSON, then load the JSON and populate a list of that new data model class.

Here is a short example of how to populate your TableView with data from any source (by utilizing the ClasamentDisp class, which holds the data from your JSON source).

import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class JsonToTableView extends Application {

    public static void main(String[] args) {

        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        // **********************************************************************************************
        // Create a basic layout
        // **********************************************************************************************
        VBox root = new VBox(5);
        root.setAlignment(Pos.TOP_CENTER);
        root.setPadding(new Insets(10));

        // **********************************************************************************************
        // Create the TableView
        // **********************************************************************************************
        final TableView<ClasamentDisp> tableView = new TableView<>();

        // **********************************************************************************************
        // Create the columns for the TableView (TableColumn cannot handle Integer for some reason, so we
        // set the data type to Number for the Score column)
        // **********************************************************************************************
        final TableColumn<ClasamentDisp, String> colParticipant = new TableColumn<>("Participant");
        final TableColumn<ClasamentDisp, Number> colScore = new TableColumn<>("Score");

        // **********************************************************************************************
        // Add the columns to the TableView (skip if defined in FXML)
        // **********************************************************************************************
        tableView.getColumns().addAll(colParticipant, colScore);

        // **********************************************************************************************
        // In order for the columns to display the properties in our ClasamentDisp objects, we need to
        // define the CellPropertyFactory for each column
        // **********************************************************************************************
        colParticipant.setCellValueFactory(c -> c.getValue().participantPropertyProperty());
        colScore.setCellValueFactory(c -> c.getValue().scorePropertyProperty());

        // **********************************************************************************************
        // Create a list to hold our Clasaments, as loaded from data source (ie: JSON)
        // **********************************************************************************************
        ObservableList<ClasamentDisp> clasaments = FXCollections.observableArrayList();
        clasaments.addAll(new ClasamentDisp("mirelradoi", 10),
                          new ClasamentDisp("test", 6),
                          new ClasamentDisp("bob", 3));

        // **********************************************************************************************
        // Set the items of the TableView to our list of loaded data
        // **********************************************************************************************
        tableView.setItems(clasaments);

        // **********************************************************************************************
        // Finally, here we add the TableView to the Scene (can be skipped if injected via FXML)
        // **********************************************************************************************
        root.getChildren().add(tableView);

        // **********************************************************************************************
        // Set the Scene for the stage
        // **********************************************************************************************
        primaryStage.setScene(new Scene(root));

        // **********************************************************************************************
        // Configure the Stage
        // **********************************************************************************************
        primaryStage.setTitle("Test Application");
        primaryStage.show();
    }
}

class ClasamentDisp {

    // **********************************************************************************************
    // Create Properties to hold the values of each item
    // **********************************************************************************************
    private final StringProperty participantProperty = new SimpleStringProperty();
    private final IntegerProperty scoreProperty = new SimpleIntegerProperty();

    public ClasamentDisp(String participant, int score) {

        this.participantProperty.setValue(participant);
        this.scoreProperty.setValue(score);
    }

    public String getParticipantProperty() {

        return participantProperty.get();
    }

    public void setParticipantProperty(String participantProperty) {

        this.participantProperty.set(participantProperty);
    }

    public StringProperty participantPropertyProperty() {

        return participantProperty;
    }

    public int getScoreProperty() {

        return scoreProperty.get();
    }

    public void setScoreProperty(int scoreProperty) {

        this.scoreProperty.set(scoreProperty);
    }

    public IntegerProperty scorePropertyProperty() {

        return scoreProperty;
    }
}

enter image description here

Zephyr
  • 9,885
  • 4
  • 28
  • 63
  • Standard naming conventions are to omit the word property from the property variable name and from the getter and setter accessors, just including it once pin the property accessor. See the naming discussion and example on defining a property in the [Oracle JavaFX properties tutorial](https://docs.oracle.com/javase/8/javafx/properties-binding-tutorial/binding.htm). – jewelsea Jan 31 '22 at 06:39
  • 1
    I agree, @jewelsea; I do not use the "property" word in normal use. I included it here just to make it clear for the OP. Of course, using IntelliJ's automatic setter/getter generation backfired here too. – Zephyr Jan 31 '22 at 13:45