将选定的行保持在表格视图控件的中间

Posted

技术标签:

【中文标题】将选定的行保持在表格视图控件的中间【英文标题】:Keeping selected row in the middle of a TablView control 【发布时间】:2014-10-03 15:00:09 【问题描述】:

无论选择如何变化,我都希望将选定的行保留在 TableView 控件的中间。我必须使用 TableView 上方的按钮(PREV、NEXT)来移动更改选定的行。问题是 TableView 滚动条没有跟随这个选择,所以我需要调用

TableView.scrollTo(int)

保持所选行可见。然而,在调用 scrollTo(int) 后,选定的行最终位于视口的顶部。我想把它放在视口的中间。

这在 Swing 中是可能的,如下所示: http://www.java2s.com/Code/Java/Swing-JFC/ScrollingaCelltotheCenterofaJTableComponent.htm

很遗憾,我无法使用 JavaFX 8 解决此问题。

【问题讨论】:

【参考方案1】:

@Jakub 之前在 Java 中建议的调用 show() 方法的示例:

TableViewSkin<?> ts = (TableViewSkin<?>) tableView.getSkin();
VirtualFlow<?> vf = (VirtualFlow<?>) ts.getChildren().get(1);
vf.show(tableView.getSelectionModel().getSelectedIndex())

我还想提请您注意,在此方法之后不建议立即调用tableViewrefresh() 方法。

【讨论】:

【参考方案2】:

刚刚为几乎相同的问题找到了更好的解决方案,不幸的是仍然是私有 API,但仅在必要时使用可变行高和滚动。我相信它与按下向上/向下箭头时调用的代码相同。 无需手动计算滚动位置,只需调用 VirtualFlow 的 .show(rowIndex)。

以下代码在 JVM1.8 下工作,它是 Kotlin,但仅在语法上与 Java 不同:

    val skin: Skin<*> = tableView.skin
    if (skin is SkinBase<*>) 
        skin.children
            .first  it is VirtualFlow<*> 
            .let  it as VirtualFlow<*> 
            .show(rowIndex)
    

请记住,VirtualFlow 是 Java 9 中的公共 API,因此需要进行一些返工(或者可能只是更改导入)。

【讨论】:

【参考方案3】:

这似乎行得通。它使用非公共 API,所以如果有人有更好的解决方案,我仍然很感兴趣。

    table.getSelectionModel().selectedIndexProperty().addListener((observable, oldValue, newValue) -> Platform.runLater(() -> 
        TableViewSkin<?> ts = (TableViewSkin<?>) table.getSkin();
        VirtualFlow<?> vf = (VirtualFlow<?>)ts.getChildren().get(1);

        int first = vf.getFirstVisibleCellWithinViewPort().getIndex();
        int last = vf.getLastVisibleCellWithinViewPort().getIndex();

        if((newValue.intValue() - ((last - first) / 2)) >= 0) 
            vf.scrollTo(newValue.intValue() - ((last - first) / 2));
        
    ));

限制是所有行必须具有相同的高度。

【讨论】:

以上是关于将选定的行保持在表格视图控件的中间的主要内容,如果未能解决你的问题,请参考以下文章

单击表格视图时如何显示选定的行?

在表格视图中选择新行时如何取消选择选定的行?

iPad:弹出视图中的表格不滚动以显示选定的行

使用 NSFetchedResultsController 和 CoreData 将选定的行传递给另一个表视图控制器

iPad:在屏幕上保留选定的表格视图单元格

表视图侧视图控制器中的当前选定行