2

In JavaFX, how to get the cell renderer instance for a given cell of a given TableColumn?

In Swing, the way to do it would be to invoke getTableCellRendererComponent() on the TableCellRenderer for that column and pass it the row and column indices. But JavaFX seems to be very different. I tried searching and going through the TableColumn API but I don't seem to be able to figure this out. Maybe I have to do something with getCellFactory().

My goal is to query the preferred width for each cell renderer of a column and then calculate the width to set on the column so that the contents of all the cells of that column are fully visible.

A question was asked here - JavaFX 2 Automatic Column Width - where the goal of the original poster was the same as that of mine. But there hasn't been a satisfactory answer there yet.

Community
  • 1
  • 1
iaswtw
  • 162
  • 1
  • 9

1 Answers1

0

There is resizeToFit() method in TableColumnHeader class. Unfortunately it is protected. How about just copy-paste the code to your application and change it a bit:

protected void resizeToFit(TableColumn col, int maxRows) {
    List<?> items = tblView.getItems();
    if (items == null || items.isEmpty()) return;

    Callback cellFactory = col.getCellFactory();
    if (cellFactory == null) return;

    TableCell cell = (TableCell) cellFactory.call(col);
    if (cell == null) return;

    // set this property to tell the TableCell we want to know its actual
    // preferred width, not the width of the associated TableColumn
    cell.getProperties().put("deferToParentPrefWidth", Boolean.TRUE);//the change is here, only the first parameter, since the original constant is not accessible outside package

    // determine cell padding
    double padding = 10;
    Node n = cell.getSkin() == null ? null : cell.getSkin().getNode();
    if (n instanceof Region) {
        Region r = (Region) n;
        padding = r.getInsets().getLeft() + r.getInsets().getRight();
    } 

    int rows = maxRows == -1 ? items.size() : Math.min(items.size(), maxRows);
    double maxWidth = 0;
    for (int row = 0; row < rows; row++) {
        cell.updateTableColumn(col);
        cell.updateTableView(tblView);
        cell.updateIndex(row);

        if ((cell.getText() != null && !cell.getText().isEmpty()) || cell.getGraphic() != null) {
            getChildren().add(cell);
            cell.impl_processCSS(false);
            maxWidth = Math.max(maxWidth, cell.prefWidth(-1));
            getChildren().remove(cell);
        }
    }

    col.impl_setWidth(maxWidth + padding);
}

Then you can call the method after load data:

for (TableColumn clm : tblView.getColumns()) {
    resizeToFit(clm, -1);
}
amru
  • 1,388
  • 11
  • 14