我想将选定的行保留在TableView控件的中间,而不管选择如何变化。我必须使用TableView上面的按钮(PREV,NEXT)来移动更改选定的行。问题是TableView滚动条不遵循此选择,因此我需要调用
TableView.scrollTo(int)的
保持选定的行可见。但是在调用scrollTo(int)后,所选行最终会出现在视口的顶部。我想把它放在视口中间。
这可以在Swing中实现,如下所示: http://www.java2s.com/Code/Java/Swing-JFC/ScrollingaCelltotheCenterofaJTableComponent.htm
不幸的是,我无法用JavaFX 8来解决这个问题。
答案 0 :(得分: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));
}
}));
限制是所有行必须具有相同的高度。
答案 1 :(得分:0)
刚刚找到稍微好一点的解决方案来解决几乎相同的问题,遗憾的是仍然是私有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,因此需要进行一些返工(或者只是更改导入)。