4

I'm having troubles accessing the objects displayed in the TableColumn

Here's the code snippet where I set the graphics of one Column. Only want to show the Name of the Person object: (Any better/easier way in doing that is welcome)

ownerColumn
            .setCellFactory(new Callback<TableColumn<Site, Person>, TableCell<Site, Person>>() {

                @Override
                public TableCell<Site, Person> call(
                        TableColumn<Site, Person> param) {

                    TableCell<Site, Person> ownerCell = new TableCell<Site, Person>() {

                        @Override
                        protected void updateItem(Person item, boolean empty) {
                            if (item != null) {
                                Label label = new Label(item.getName());
                                setGraphic(label);
                            }
                        }
                    };
                    return ownerCell;
                }
            });

Now I'm trying to loop through the rows and columns go get every cell to generate a report at the end, reflecting the displayed text/graphics in the Tableview. Like this

for (Object r : this.tableview.getItems()) {
        for (Object c : this.tableview.getColumns()) {
            javafx.scene.control.TableColumn column = (javafx.scene.control.TableColumn) c;

            if (column.getCellData(r) != null) {
                // I get the object bound to the cell here, but I only want
                // to have what i've set as graphics - what the user sees on UI
                // How to use getGraphics() ?
            }
        }
    }

So the question is, how do I get the getGraphics() I've set in the CellFactory?

Mike P.
  • 41
  • 1
  • 1
  • 2

3 Answers3

2

A static method for any type of cell content.

Method getItems() gets the value of the property items. Property is the underlying data model for the TableView. Note that it has a generic type that must match the type of the TableView itself.

  private static ArrayList<String> getTableViewValues(TableView tableView) {
    ArrayList<String> values = new ArrayList<>();
    ObservableList<TableColumn> columns = tableView.getColumns();

    for (Object row : tableView.getItems()) {
      for (TableColumn column : columns) {
        values.add(
          (String) column.
          getCellObservableValue(row).
          getValue());
      }
    }

    return values;
  }
Zon
  • 18,610
  • 7
  • 91
  • 99
1

This approach, accessing the Cell, will not work, as the CellFactory will not be used to produce a 1:1 Cell for each row. The Cell is only used as a lightweight View generator and will be reused heavily.

By the way you might use:

@Override
protected void updateItem(Person item, boolean empty) {
    super.updateItem(item, empty);
    if (item != null && !empty) {
        setText(item.getName());
    } else {
        setText(null);
    }
}

will simply show a text.

a) Check also the boolean empty

b) Explicitely clear all graphic/text that will be set (test here) due to the reuse cases!

c) Always call the super udateItem() method.

Jens-Peter Haack
  • 1,887
  • 13
  • 18
  • Thank you Jens, appreciate your answer. I'll definitely try this approach, how could I set a checkbox then to visualise a boolean? I do the same as in my original post, just use a CheckBox instead of an Label. I come from C# where I can easily access what ever is displayed to the user. But I really tried hard to get it with JavaFX TableView. The thing is, i wanted to have one PDF Report generator that takes a TableView as parameter and generates a representation of that as a PDF, but as my problem I could not access the displayed object. – Mike P. Nov 08 '14 at 15:13
  • For CheckBoxes see: http://stackoverflow.com/questions/20879242/get-checkbox-value-in-a-table-in-javafx, there you have to use the setGraphics() way... – Jens-Peter Haack Nov 08 '14 at 15:16
  • You don't need to call `setGraphic()`. Just use [`CheckBoxTableCell`](http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/cell/CheckBoxTableCell.html) and provide the [callback to the boolean property in the model](http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/cell/CheckBoxTableCell.html#selectedStateCallbackProperty). – James_D Nov 08 '14 at 16:36
  • Either way I set the text, I still can not access getGraphics of TabelColumn what was my plan. Will check if your way of setting the TableCell is working any better. – Mike P. Nov 08 '14 at 16:41
1

As Jens-Peter says, there isn't a 1-1 correspondence between cells and items in the table, so the approach of getting the cell will not work.

You should think of table.getItems() as having the data that's displayed. The table, table columns, and table cells are just visualizations of those data. Refer back to the actual data, not to the specific visualization of it:

for (Site site : tableView.getItems()) {
    // owner column data:
    Person owner = site.getOwner();
    String ownerName = owner.getName();
    // ...
}
James_D
  • 201,275
  • 16
  • 291
  • 322
  • Thank you as well James. In addition to my comments on Jens answer, I know that would be a solution to it without a question, but my goal was to get a reporter class that takes a TableView as parameter and generates a PDF out of the visualisation, no matter if text, checkbox or what ever else is there. Of course I'd have to display it different by what ever Type the visualised object is, but apparently thats not gonna work out... – Mike P. Nov 08 '14 at 15:19
  • Do you want a screenshot, or are you effectively looking to provide an alternative view of the data (as a pdf)? – James_D Nov 08 '14 at 16:32
  • I need to have a PDF 'printout' of the different TabelViews I have, I started to use iText and seems pretty easy to handle. – Mike P. Nov 08 '14 at 16:39
  • tableView.getItems returns Object, so I am not sure this would work – serup Jun 24 '16 at 12:53
  • 2
    @serup No, it returns an [`ObservableList`](http://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TableView.html#getItems--). Assuming your table is declared correctly (i.e. as a `TableView`) then it returns an `ObservableList`, and the code will work. – James_D Jun 24 '16 at 13:08
  • Thanks for clarifying – serup Jul 06 '16 at 07:47