【问题标题】:JavaFX 9/10 no longer possible to override TableView.resizeColumnToFitContentJavaFX 9/10 不再可能覆盖 TableView.resizeColumnToFitContent
【发布时间】:2018-11-08 01:59:19
【问题描述】:

在 JavaFX 8 中,可以覆盖 TableView.resizeColumnToFitContent 函数。这对我们的目的至关重要,因为它允许我们在默认实现之外增强列标题的布局方式,以及在较大的表中调整默认值的性能。

如何增强布局行为的一个例子是在嵌套列标题的上下文中。默认情况下,叶列标题的 prefWidth 根据该列中数据行的最大宽度或叶列标题文本的宽度设置,以较大者为准。但是,如果该叶子标题有一些父列标题具有更宽的标题文本,它们将被剪裁并显示一个省略号。这对我们来说是不可取的,因此我们更改了resizeColumnToFitContent,因此叶列标题的 prefWidth 也考虑了其父列标题的 prefWidth。

从 Java 9 和以下提交开始,resizeColumnToFitContent 函数已移至静态位置,从而无法自定义此行为:

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

大约一周前,我写信给负责此更改的作者 Jonathan Giles,但我猜他是个忙碌的人,这正在成为我们以及我们将产品迁移到 Java 10 的计划的阻碍问题,所以我想我还想看看社区是否知道我可以如何解决这个问题。到目前为止,唯一的选择似乎是有点蛮力的方法outlined here,但也许有更好的方法?

【问题讨论】:

  • FWIW,乔纳森不再为甲骨文工作。这种方法实际上从来都不是公共 API 的一部分,是吗?
  • James 是对的——我不再在 Oracle 工作,也不再负责那里的任何代码 :-) 我建议你采取蛮力方法——这基本上就是你想要公开的代码所做的无论如何(从记忆中)
  • 为什么这个函数不能成为受保护 API 的一部分? TableView 是 JavaFX 中的核心控件,应该尽可能地扩展,而不必诉诸蛮力。你认为值得我花时间向 OpenJDK 提交 PR 来实现吗?
  • 基本上,继承在某种程度上破坏了封装,因为要覆盖一个方法,您必须了解该方法的实现。这意味着如果 API 允许重写某个方法,那么它将始终将该 API 提交给该特定实现。当皮肤类在 Java 9 中移至公共 API 时,一些方法被设为私有(或移至实用程序类);大概这些是 JavaFX 团队尚未准备好提交所使用的特定实现的方法。如果您还没有,请阅读 Josh Bloch 的“Effective Java”。
  • James 是对的(再次)——API 设计的最佳方法是缓慢而谨慎。制作一个“尽可能可扩展”的 API 是一件非常困难的事情,因为这意味着我们基本上只是将整个实现公开,这使我们永远无法更改与代码相关的任何内容,因为这意味着我们可能会破坏某人。这就是为什么首先将 API 和实现的概念分开的原因 - 像这里所做的那样依赖实现是不明智的,因为不能保证它会保持稳定。

标签: java javafx tableview java-9 java-10


【解决方案1】:

如果你想重写这个方法,为什么你不实现你自己的 resizeColumnToFitContent 就像在 TableSkinUtils 中那样?

【讨论】:

  • 该方法是从其中一个皮肤类(TableColumnHeader,也许还有其他)中的private 方法调用的,因此您不能覆盖调用它的方法。因此,可能是设计使然,没有办法重新定义这种行为。 (你基本上最终会从头开始重新实现几乎所有的皮肤。)
  • @James_D 确实是这样,有许多相关的类需要重新实现
【解决方案2】:

借助 Java 16,我们现在可以以新的方式访问 resizeColumnToFitContent

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多