Coding the JavaFX TableView
Step 4: Wire Up the Controls
Next, go back to Scene Builder and wire up the button, TableView, and each TableRow component to each FXML declaration in the code with the matching name. Do this within the Properties section in Scene Builder. Save the file, and get ready to complete the table sample.
Step 5: Initialize the TableView
We're almost done. All we need to do is add code to initialize the table, and then wire up the button on the window to use binding to add items. First, make your application main class implement the javafx.fxml.Initializable
interface, as shown here:
public class InvoiceTable extends Application implements Initializable { //... }
With this interface, you need to implement the initialize()
method, which the JavaFX runtime will call for you when the window is first displayed:
@Override public void initialize(URL url, ResourceBundle rb) { //... }
Next, you need to set up the table's columns by telling each column which part of the InvoiceEntry
class it maps to. The name in quotes must match a field in the class, which must have the appropriately named getter method (i.e. "itemId" must have a getItemId()
method):
// Set up the invoice table itemIdCol.setCellValueFactory( new PropertyValueFactory<InvoiceEntry,Integer>("itemId") ); itemNameCol.setCellValueFactory( new PropertyValueFactory<InvoiceEntry,String>("itemName") ); itemQtyCol.setCellValueFactory( new PropertyValueFactory<InvoiceEntry,Integer>("qty") ); itemPriceCol.setCellValueFactory( new PropertyValueFactory<InvoiceEntry,String>("price") );
Note that columns that display String
s must map to a class field of type javafx.beans.property.SimpleStringProperty
, Integer
s must map to javafx.beans.property.SimpleIntegerProperty
, and so on. This sets up the relationship between the table column and the data, and allows binding to work.
Next, adding data to the table is done with two lines of code; the first to create an ObservableList
(again, for binding), and the next to assign it to the table as its data:
data = FXCollections.observableArrayList(); // create the data invoiceTbl.setItems(data); // assign the data to the table
Whenever a new InvoiceEntry
is added to this ObservableList
, from anywhere in the application, the TableView control will automatically be updated via JavaFX binding. To implement this, add the generateInvoiceEntry()
method, as shown here:
private void generateInvoiceEntry() { // Add to the data any time, and the table will be updated InvoiceEntry entry = new InvoiceEntry(); itemNum++; entry.itemId.set(itemNum); entry.itemName.set("Item " + itemNum); entry.price.set("" + (1.99 + itemNum) ); entry.qty.set(itemNum + 10); data.add(entry); }
Step 6: Add Entries to the TableView
The generateInvoiceEntry()
method generates a new InvoiceEntry
object with incrementing values, and adds it to the ObservableList
, data
. You can call this method in the onAddItem()
method, which itself gets called when you click on the "Add Item" button:
public void onAddItem(ActionEvent event) { // Add to the data any time, and the table will be updated generateInvoiceEntry(); }
All Done! Go ahead and run the application, and click the "Add Item" button repeatedly to see how binding updates the table for you. In the end, not much code is needed to get a bunch of functionality with JavaFX 2.0.
Happy Coding!
—EJB