【发布时间】:2021-01-20 13:23:22
【问题描述】:
VirtualFlow 的当前实现仅在视图 rect 小于控件大小时才显示滚动条。我所说的控件是指 ListView、TreeView 和任何标准的虚拟化控件。问题是垂直滚动条的出现会导致控件宽度的重新计算,即它会将单元格内容略微移动到左侧。这是明显明显且非常不舒服的运动。
我需要预先为垂直滚动条预留一些空间,但是没有一个控件提供 API 来操作 VirtualFlow 滚动条的行为,这是非常不幸的 API 设计。更不用说大多数实现都将滚动条放在组件的顶部,因此只是重叠了它的一小部分。
问题是,“实现这一目标的最佳方法是什么?”。填充无济于事,JavaFX 没有边距支持。我可以将控制(例如 ListView)放在 ScrollPane 中,但我敢打赌 VirtualFlow 在这种情况下不会继续重用单元格,所以这不是一个解决方案。
示例:
展开和折叠node2,它会移动lbRight 的内容。
public class Launcher extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
TreeItem<UUID> root = new TreeItem<>(UUID.randomUUID());
TreeView<UUID> tree = new TreeView<>(root);
tree.setCellFactory(list -> new CustomCell());
TreeItem<UUID> node0 = new TreeItem<>(UUID.randomUUID());
TreeItem<UUID> node1 = new TreeItem<>(UUID.randomUUID());
TreeItem<UUID> node2 = new TreeItem<>(UUID.randomUUID());
IntStream.range(0, 100)
.mapToObj(index -> new TreeItem<>(UUID.randomUUID()))
.forEach(node2.getChildren()::add);
root.getChildren().setAll(node0, node1, node2);
root.setExpanded(true);
node2.setExpanded(true);
BorderPane pane = new BorderPane();
pane.setCenter(tree);
Scene scene = new Scene(pane, 600, 600);
primaryStage.setTitle("Demo");
primaryStage.setScene(scene);
primaryStage.setOnCloseRequest(t -> Platform.exit());
primaryStage.show();
}
static class CustomCell extends TreeCell<UUID> {
public HBox hBox;
public Label lbLeft;
public Label lbRight;
public CustomCell() {
hBox = new HBox();
lbLeft = new Label();
lbRight = new Label();
lbRight.setStyle("-fx-padding: 0 20 0 0");
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
hBox.getChildren().setAll(lbLeft, spacer, lbRight);
}
@Override
protected void updateItem(UUID uuid, boolean empty) {
super.updateItem(uuid, empty);
if (empty) {
setGraphic(null);
return;
}
String s = uuid.toString();
lbLeft.setText(s.substring(0, 6));
lbRight.setText(s.substring(6, 12));
setGraphic(hBox);
}
}
}
【问题讨论】:
-
在自定义要求未得到满足时一如既往:自行实现 :) 在这里,您需要使用自定义虚拟流的自定义皮肤。无论如何,第一步是确切地指定你想要什么,清楚地考虑约束。
-
垂直滚动条的出现会导致控件宽度的重新计算 真的吗?举个例子来说明你的意思怎么样?
-
@kleopatra 这几乎不是定制的。这是任何其他主要 UI 工具包默认实现的唯一合理行为
¯\_(ツ)_/¯请注意 Qt 或 GTK 小部件如何显示滚动条。它总是在顶部。至于你的建议,嗯……谢谢……但实施起来非常棘手。 -
其他框架做什么并不重要,是吗 ;) 我的意思是 custom 就像 fx 在 not-provided 中一样 - 他们有一个像他们那样实施的理由。保持领先(因此可能隐藏单元格内容)并不是天生就更好,只是不同的 IMO。是的,我知道要更改 VirtualFlow 并不简单,我去过那里 ;) 无论如何,您仍然没有指定确切您想要什么。否则,此问题在本网站范围内无法回答。
-
.. 按原样,这听起来更像是在抱怨您认为缺少什么:提供 API 来操作 VirtualFlow 滚动条行为,这是非常不幸的 API 设计 ..好吧,也许或不......要走的路:指定你想要的api并自己实现它和/或提交一个增强问题,贡献你实现的东西:)
标签: java javafx scroll scrollbar