Friday, April 13, 2012

JavaFX 2: TableView

JavaFX provide API of TableView, TableColumn, and TableCell to help creating tables. You can populate a table by implementing the data model and by applying a cell factory.

The table classes provide built-in capabilities to sort data in columns and to resize columns when necessary.

It's a example of JavaFX 2 TableView.

JavaFX 2: TableView

Please note that the setCellValueFactory() method specifies a cell factory for each column. It uses the "
fieldMonth", "fieldValue" properties of the table columns as references to the corresponding methods of the Record class. It assume that there are callback method named getFieldMonth() and getFieldValue() in Record class.
Remark - if you name it getfieldMonth() and getfieldValue(); it will not work!

~ Ref: http://docs.oracle.com/javafx/2.0/api/javafx/scene/control/cell/PropertyValueFactory.html

package javafx_table;

import javafx.application.Application;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
*
* @web http://java-buddy.blogspot.com/
*/
public class JavaFX_TableView extends Application {

  public class Record{
      private SimpleStringProperty fieldMonth;
      private SimpleDoubleProperty fieldValue;
    
      Record(String fMonth, double fValue){
          this.fieldMonth = new SimpleStringProperty(fMonth);
          this.fieldValue = new SimpleDoubleProperty(fValue);
      }
    
      public String getFieldMonth() {
          return fieldMonth.get();
      }
    
      public double getFieldValue() {
          return fieldValue.get();
      }
    
  }

  private TableView<Record> tableView = new TableView<>();

  private ObservableList<Record> dataList =
          FXCollections.observableArrayList(          
              new Record("January", 100),
              new Record("February", 200),
              new Record("March", 50),
              new Record("April", 75),
              new Record("May", 110),
              new Record("June", 300),
              new Record("July", 111),
              new Record("August", 30),
              new Record("September", 75),
              new Record("October", 55),
              new Record("November", 225),
              new Record("December", 99));

  /**
   * @param args the command line arguments
   */
  public static void main(String[] args) {
      launch(args);
  }

  @Override
  public void start(Stage primaryStage) {
      primaryStage.setTitle("java-buddy.blogspot.com");
    
      Group root = new Group();

      TableColumn columnMonth = new TableColumn("Month");
      columnMonth.setCellValueFactory(
              new PropertyValueFactory<Record,String>("fieldMonth"));

      TableColumn columnValue = new TableColumn("Value");
      columnValue.setCellValueFactory(
              new PropertyValueFactory<Record,Double>("fieldValue"));
    
      tableView.setItems(dataList);
      tableView.getColumns().addAll(columnMonth, columnValue);
    
      VBox vBox = new VBox();
      vBox.setSpacing(10);
      vBox.getChildren().add(tableView);

      root.getChildren().add(vBox);
    
      primaryStage.setScene(new Scene(root, 300, 250));
      primaryStage.show();
  }
}


Next:
- Editable TableView


More:
Read csv file, display in JavaFX TableView
Read csv, run in background thread and update JavaFX TableView dynamically

7 comments:

  1. I would like to take this one step further.. and how do I do this, because I can't figure it out. Keep your same columns, but have a top column , maybe labeled YEAR. Put 10 of those across.. So, for EACH YEAR, you have your 12 months and the data associated. I can make the Top title and the two sub columns easily enough with JAVAFX, but I can't figure out how to couple the TableView with the data list... how to get the Column I am in, which is needed to fetch the correct info from the list? Any ideas? This is a quite common function, there has to be a way to do this!

    ReplyDelete
    Replies
    1. No, that example you show is very easy to do. I had added a jpg to this thread to show a real example of what I want to do. I do not know how to paste that example into this thread..

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Solved! Very happy, but SOLVED!

    You can see my solution result at

    http://www.throwarock.com/javafx/DepthOfField.html

    Once I understood what I needed to provide to both e cellFactory and to the cellFactoryValue..it was easy to finish.. I do not understand how to get the table to scroll laterally.. but, this is my prototype, and I would be more than happy to share my whole solution. I think your readers would be interested. I still think the correct solution would be to have tableview accept an array or map observablelist, but my solution works here.

    ReplyDelete
  4. I'm testing myself with a simple CSV Viewer using JavaFX and I'm stuck at populating the table data. I do create the columns dynamically, but the data values are a no-go.

    ReplyDelete