【问题标题】:How to extend JavaFX Pagination navigation to display additional controls?如何扩展 JavaFX 分页导航以显示其他控件?
【发布时间】:2015-07-21 13:10:45
【问题描述】:

我想使用分页来明智地显示表格页面。这原则上可行,但我想添加与默认分页导航位于同一行的其他控件:

  • 转到首页的按钮(“
  • 用于跳转到指定页面索引的文本字段
  • 转到最后一页的按钮(“>>”)
  • 每页条目数的文本字段
  • 搜索文本字段以跳转到包含具有给定 ID 的行条目的页面。

我可以使用 setPageFactory() 方法自定义分页控件上方的页面,但我无法自定义导航控件本身。怎么做?如果我在默认导航上方或下方添加其他控件,我会浪费一些空间:

相关文章: JavaFX Pagination, adding << and >>> options

提交了enhancement request

【问题讨论】:

  • 不支持自定义导航 - 它是一个包私有类 (NavigationControl),它被硬编码并硬连接到 PaginationSkin 中。您唯一的选择(我可以看到)是使用自定义导航控件滚动您自己的皮肤(主要是 c&p)(但从未尝试过)
  • 我没有检查,但如果这不能用公共 API 更改,您可能需要提交增强请求:bugs.java.com

标签: java layout pagination javafx-8


【解决方案1】:

不支持自定义导航控件。在等待修复 the enhancement request 时,我们可以应用如下所述的 hack(如果 QA 指南允许)。这是一个 hack,因为与导航控件相关的所有内容都是 PaginationSkin 中的私有包,它本身不是(还)公共 api。

基本思想是在核心导航控件中插入额外的节点,这显然意味着依赖于实现细节(dont, dont, dont :-)。我们在实例化时即时执行此操作,并且每当再次插入下一个按钮时 - 核心在布局和分页状态更改期间经常清除其所有子项。这涉及:

  • 查找包含按钮的窗格,它的选择器是控制框
  • 保留对其最后一个子元素的引用,即下一个按钮
  • 向窗格的子级添加侦听器,以便能够插入自定义控件

自定义皮肤的代码示例,这里只是第一个/最后一个按钮:

public static class CustomPaginationSkin extends PaginationSkin {

    private HBox controlBox;
    private Button prev;
    private Button next;
    private Button first;
    private Button last;

    private void patchNavigation() {
        Pagination pagination = getSkinnable();
        Node control = pagination.lookup(".control-box");
        if (!(control instanceof HBox))
            return;
        controlBox = (HBox) control;
        prev = (Button) controlBox.getChildren().get(0);
        next = (Button) controlBox.getChildren().get(controlBox.getChildren().size() - 1);

        first = new Button("A");
        first.setOnAction(e -> {
            pagination.setCurrentPageIndex(0);
        });
        first.disableProperty().bind(
                pagination.currentPageIndexProperty().isEqualTo(0));

        last = new Button("Z");
        last.setOnAction(e -> {
            pagination.setCurrentPageIndex(pagination.getPageCount());
        });
        last.disableProperty().bind(
                pagination.currentPageIndexProperty().isEqualTo(
                        pagination.getPageCount() - 1));

        ListChangeListener childrenListener = c -> {
            while (c.next()) {
                // implementation detail: when nextButton is added, the setup is complete
                if (c.wasAdded() && !c.wasRemoved() // real addition
                        && c.getAddedSize() == 1 // single addition
                        && c.getAddedSubList().get(0) == next) { 
                    addCustomNodes();
                }
            }
        };
        controlBox.getChildren().addListener(childrenListener);
        addCustomNodes();
    }

    protected void addCustomNodes() {
        // guarding against duplicate child exception 
        // (some weird internals that I don't fully understand...)
        if (first.getParent() == controlBox) return;
        controlBox.getChildren().add(0, first);
        controlBox.getChildren().add(last);
    }

    /**
     * @param pagination
     */
    public CustomPaginationSkin(Pagination pagination) {
        super(pagination);
        patchNavigation();
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-14
    • 2021-03-12
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 2018-02-28
    • 1970-01-01
    相关资源
    最近更新 更多