24

I would like to know how do I populate a TableView with data... All the examples I have seen creates a TableView with columns and everything and add it to the scene. All done in the java code itself.

What I want to know: if I design my "form" in JavaFx Scene builder. Defining all the tables and columns in there. How do I access it to populate it from java? Or if someone can point me to a proper tutorial on this please.

I have defined my form in JavaFx Scene Builder - only a TableView with 3 Columns

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>

<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="288.0" prefWidth="293.0" xmlns:fx="http://javafx.com/fxml">
<children>
    <TableView fx:id="tableView" layoutX="35.0" layoutY="28.0" prefHeight="200.0" prefWidth="227.0">
    <columns>
        <TableColumn prefWidth="75.0" text="UserId" fx:id="UserId" />
        <TableColumn prefWidth="75.0" text="UserName" fx:id="UserName" />
        <TableColumn prefWidth="75.0" text="Active" fx:id="Active" />
    </columns>
    </TableView>
</children>
</AnchorPane>

I have my data in a ResultSet in my Java code.

ResultSet rs = c.createStatement().executeQuery(SQL);

I need to populate the TableView.

Thanks

cp5
  • 1,087
  • 6
  • 26
  • 58

2 Answers2

61

To access to tableview you need to define a controller of your FXML page. Add

fx:controller="path.to.MyController"

attribute to the AnchorPane in FXML file. Then create the controller and link TableView, TableColumns from FXML file by putting @FXML annotation in front of these variables:

package path.to;

public class MyController implements Initializable {

    @FXML private TableView<User> tableView;
    @FXML private TableColumn<User, String> UserId;
    @FXML private TableColumn<User, String> UserName;
    @FXML private TableColumn<User, String> Active;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        UserId.setCellValueFactory(new PropertyValueFactory<User, String>("id"));
        UserName.setCellValueFactory(new PropertyValueFactory<User, String>("name"));
        Active.setCellValueFactory(new PropertyValueFactory<User, String>("active"));

        tableView.getItems().setAll(parseUserList());
    }
    private List<User> parseUserList(){
        // parse and construct User datamodel list by looping your ResultSet rs
        // and return the list   
    }
}

The tableview is populated in the initialize method. Note that in controller we are not creating new tableview or tablecolumns, since they are already created whlle the FXML file is being loaded. Also note that the TableView and Tablecolumn variable names must be the same with fx:id values in the corresponding FXML file. So while UserId, UserName and Active names are not convenient namings, change them both in FXML file and in Controller to names like userIdCol, userNameCol and userActiveCol respectively.

Uluk Biy
  • 48,655
  • 13
  • 146
  • 153
  • Thanks-didn't knew about the controllers :) – cp5 Jul 01 '12 at 12:02
  • 4
    What should be in the class User? – Chiranjib Oct 24 '14 at 19:08
  • 4
    Thanks for this answer. A quick note though: the Initializable interface is no longer required. You do not have to implement it. Just have a method in your Controller: `@FXML private void initialize()` and it will be called by the FXMLLoader. [Proof in docs](http://download.java.net/jdk8/jfxdocs/javafx/fxml/Initializable.html) – alisianoi Mar 10 '16 at 22:05
  • 1
    Yeah @all3fox now it is not mandatory. Will update the post accordingly. Thanks. – Uluk Biy Mar 11 '16 at 17:27
  • 1
    Even though it is an old post, it saved my day. I had to vote it up. – CN1002 Mar 12 '16 at 12:36
  • That's interesting.. I used the method suggested by 'all3fox' and IntelliJ IDEA marked the method `initialize()` as never used. It works fine though. – Mario Geuenich May 29 '17 at 11:12
  • Isn't this (and the answer below) kinda repetitive? Isn't there a way to iterate through the list and set the the cellValueFactory? – OzzyTheGiant Sep 25 '17 at 03:12
  • @Chiranjib check out this for info on that: http://www.java2s.com/Tutorials/Java/JavaFX/0650__JavaFX_TableView.htm –  Jan 29 '18 at 22:35
  • @Chiranjib The class must contain getters – Cl00e9ment Dec 05 '21 at 19:19
1

Yo can do this in your controller:

 @FXML
private TableView<User> table;
private List<User> users;

@Override
public void initialize(URL url, ResourceBundle rb) {
    // Set the columns width auto size
    table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
    table.getColumns().get(0).prefWidthProperty().bind(table.widthProperty().multiply(0.33));    // 33% for id column size
    table.getColumns().get(1).prefWidthProperty().bind(table.widthProperty().multiply(0.33));   // 33% for dt column size
    table.getColumns().get(2).prefWidthProperty().bind(table.widthProperty().multiply(0.33));    // 33% for cv column size
    table.getItems().setAll(this.users);
}
Marlord
  • 1,144
  • 2
  • 13
  • 24