public class NewMain extends Application {
public class VirtualCell extends IndexedCell<String> {
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
} else {
setText(item);
setMinHeight(250); // 250 > scene height
setPrefHeight(250); // 250 > scene height
}
}
@Override
protected Skin<?> createDefaultSkin() {
return new CellSkinBase<>(this);
}
}
private static class MyVirtualFlow extends VirtualFlow<VirtualCell> {
public MyVirtualFlow() {
getVbar().setVisible(false);
setVertical(false);
}
}
private MyVirtualFlow virtualFlow = new MyVirtualFlow();
@Override
public void start(Stage primaryStage) {
List<String> list = new ArrayList<>();
for (var i = 0; i < 100; i++) {
list.add("Item " + i);
}
ObservableList<String> items = FXCollections.observableArrayList(list);
virtualFlow.setCellFactory(vf -> new VirtualCell());
virtualFlow.setCellCount(items.size());
virtualFlow.setCellFactory(vf -> new VirtualCell() {
@Override
public void updateIndex(int index) {
super.updateIndex(index);
if (index >= 0 && index < items.size()) {
updateItem(items.get(index), false);
} else {
updateItem(null, true);
}
}
});
VBox.setVgrow(virtualFlow, Priority.ALWAYS);
var root = new VBox(this.virtualFlow);
Scene scene = new Scene(root, 400, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
当您看到我尝试使用
getVbar().setVisible(false);
构造器中的VirtualFlow
将其删除。但这无效。如果可能的话,任何人都可以说如何做。
首先,我同意@Jewelsea和@slaw提供的所有建议。您正在违反虚拟流的目的。但是,如果您拼命想尝试一下,以下是一种可以尝试接近的方法。 注:我不建议这种方法。唯一的目的是让您知道为什么设置可见的设置将无法修复和解决方法。 尽管仅每个虚拟集实例启动一次滚动条,但其可见性是根据虚拟流的当前状态动态计算的。通过调用ComputeBarvisiBlity(),以LayoutChildren()方法重新计算了滚动条的可见性。该方法的代码如下。
private boolean computeBarVisiblity() {
if (cells.isEmpty()) {
// In case no cells are set yet, we assume no bars are needed
needLengthBar = false;
needBreadthBar = false;
return true;
}
final boolean isVertical = isVertical();
boolean barVisibilityChanged = false;
VirtualScrollBar breadthBar = isVertical ? hbar : vbar;
VirtualScrollBar lengthBar = isVertical ? vbar : hbar;
final double viewportBreadth = getViewportBreadth();
final int cellsSize = cells.size();
final int cellCount = getCellCount();
for (int i = 0; i < 2; i++) {
final boolean lengthBarVisible = getPosition() > 0
|| cellCount > cellsSize
|| (cellCount == cellsSize && (getCellPosition(cells.getLast()) + getCellLength(cells.getLast())) > getViewportLength())
|| (cellCount == cellsSize - 1 && barVisibilityChanged && needBreadthBar);
if (lengthBarVisible ^ needLengthBar) {
needLengthBar = lengthBarVisible;
barVisibilityChanged = true;
}
final boolean breadthBarVisible = !suppressBreadthBar && (maxPrefBreadth > viewportBreadth);
if (breadthBarVisible ^ needBreadthBar) {
needBreadthBar = breadthBarVisible;
barVisibilityChanged = true;
}
}
// Start by optimistically deciding whether the length bar and
// breadth bar are needed and adjust the viewport dimensions
// accordingly. If during layout we find that one or the other of the
// bars actually is needed, then we will perform a cleanup pass
if (!Properties.IS_TOUCH_SUPPORTED) {
updateViewportDimensions();
breadthBar.setVisible(needBreadthBar);
lengthBar.setVisible(needLengthBar);
} else {
breadthBar.setVisible(needBreadthBar && tempVisibility);
lengthBar.setVisible(needLengthBar && tempVisibility);
}
return barVisibilityChanged;
}
因此,将可见度设置在某一时刻将无法正常工作,并且将被覆盖。
一种修复此操作以将VBAR的优势设置为0的方法,以便布局计算忽略VBAR。但是,仅将前放置设置为0是不够的。 INC/DEC按钮的箭头可见(我尚未检查为什么会发生。)。为了解决该问题,您可以将VBAR的不透明度设置为0。
您在更新以下更改为myVirtualFlow的更改,不再可见VBAR。
option#1 :(使用API)
private static class MyVirtualFlow extends VirtualFlow<VirtualCell> {
public MyVirtualFlow() {
setVertical(false);
getVbar().setPrefWidth(0);
getVbar().setOpacity(0);
}
}
private static class MyVirtualFlow extends VirtualFlow<VirtualCell> {
private final static String CSS = "data:text/css," +
"""
.virtual-flow > .scroll-bar:vertical{
-fx-pref-width: 0px;
}
.virtual-flow > .scroll-bar:vertical .increment-arrow,
.virtual-flow > .scroll-bar:vertical .decrement-arrow{
-fx-padding: 0px;
}
""";
public MyVirtualFlow() {
setVertical(false);
getStylesheets().add(CSS);
}
}