简体   繁体   中英

JavaFX 8 : Iterate through TableView cells and get graphics

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?

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;
  }

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.

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();
    // ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM