EdK
EdK

Reputation: 91

JavaFX 9/10 no longer possible to override TableView.resizeColumnToFitContent

In JavaFX 8 it was possible to override the TableView.resizeColumnToFitContent function. This is vital for our purposes since it allows us to enhance the way column headers are laid out beyond the default implementation, as well as to tune the performance where the default suffers somewhat in larger tables.

One example of how the layout behaviour has been enhanced is in the context of nested column headers. By default a leaf column header's prefWidth is set according to either the max width of the rows of data in that column, or to the width of the leaf column's title text, whichever is greater. But if that leaf header has some parent column headers with wider title text, they'll be clipped and an ellipsis displayed. This is not desirable for us, so we've changed resizeColumnToFitContent so the prefWidth of a leaf column header also takes into account the prefWidth of its parent column headers.

As of Java 9 and the below commit, the resizeColumnToFitContent function has been moved to a static location, removing the ability to customise this behaviour:

http://hg.openjdk.java.net/openjfx/9-dev/rt/rev/53bfdfed5bbf

About a week ago I wrote to the author responsible for this change, Jonathan Giles, but I guess he's a busy guy and this is becoming a blocking issue for us and our plans to migrate our product to Java 10, so I thought I'd also see if the community knows how I might solve this. So far, the only option seems to be the somewhat brute force approach outlined here, but maybe there's a better way?

Upvotes: 1

Views: 1145

Answers (2)

RainerMtb
RainerMtb

Reputation: 366

With Java 16 we can now get access to resizeColumnToFitContent in a new way

class FitWidthTableView<T> extends TableView<T> {
    
    public FitWidthTableView() {
        setSkin(new FitWidthTableViewSkin<>(this));
    }

    public void resizeColumnsToFitContent() {
        Skin<?> skin = getSkin();
        if (skin instanceof FitWidthTableViewSkin<?> ctvs) ctvs.resizeColumnsToFitContent();
    }
}

class FitWidthTableViewSkin<T> extends TableViewSkin<T> {
    
    public FitWidthTableViewSkin(TableView<T> tableView) {
        super(tableView);
    }

    @Override
    protected TableHeaderRow createTableHeaderRow() {
        return new TableHeaderRow(this) {
            
            @Override
            protected NestedTableColumnHeader createRootHeader() {
                return new NestedTableColumnHeader(null) {
                    
                    @Override
                    protected TableColumnHeader createTableColumnHeader(TableColumnBase col) {
                        return new FitWidthTableColumnHeader(col);
                    }
                };
            }
        };
    }

    public void resizeColumnsToFitContent() {
        for (TableColumnHeader columnHeader : getTableHeaderRow().getRootHeader().getColumnHeaders()) {
            if (columnHeader instanceof FitWidthTableColumnHeader colHead) colHead.resizeColumnToFitContent(-1);
        }
    }
}

class FitWidthTableColumnHeader extends TableColumnHeader {
    
    public FitWidthTableColumnHeader(TableColumnBase col) {
        super(col);
    }

    @Override
    public void resizeColumnToFitContent(int rows) {
        super.resizeColumnToFitContent(-1);
    }
}

Upvotes: 1

baalus
baalus

Reputation: 11

If you want to override this method, why you just don't implement your own resizeColumnToFitContent like is was in TableSkinUtils ?

Upvotes: 1

Related Questions