Программный выбор JavaFX ListView прокручивается только тогда, когда элемент находится за пределами видимого диапазонаJAVA

Программисты JAVA общаются здесь
Anonymous
Программный выбор JavaFX ListView прокручивается только тогда, когда элемент находится за пределами видимого диапазона

Сообщение Anonymous »

При программном выборе элементов в ListView я хочу, чтобы прокрутка вела себя как навигация с помощью встроенной клавиатуры — прокрутка выполнялась только тогда, когда выбранный элемент находится за пределами видимой области. Использование listView.scrollTo(index) всегда меняет положение представления, что кажется неестественным. Вот мой код:

Код: Выделить всё

public class Test1 extends Application {

@Override
public void start(Stage stage) {
ListView listView = new ListView();
listView.getItems().addAll(
IntStream.rangeClosed(1, 30)
.mapToObj(i -> "Item " + i)
.collect(Collectors.toList())
);
listView.setPrefHeight(200);
listView.getSelectionModel().select(0);

Button up = new Button("Up");
Button down = new Button("Down");

up.setOnAction(e -> {
int index = listView.getSelectionModel().getSelectedIndex();
if (index > 0) {
listView.getSelectionModel().select(index - 1);
scrollToIfNeeded(listView, index - 1);
}
});

down.setOnAction(e -> {
int index = listView.getSelectionModel().getSelectedIndex();
if (index < listView.getItems().size() - 1) {
listView.getSelectionModel().select(index + 1);
scrollToIfNeeded(listView, index + 1);
}
});

HBox buttons = new HBox(10, up, down);
VBox root = new VBox(10, listView, buttons);
root.setPadding(new Insets(10));

stage.setScene(new Scene(root, 300, 300));
stage.show();
}

private void scrollToIfNeeded(ListView listView, int index) {
VirtualFlow flow = (VirtualFlow) listView.lookup(".virtual-flow");
if (flow == null) {
return;
}

var firstCell = flow.getFirstVisibleCell();
var lastCell = flow.getLastVisibleCell();
if (firstCell == null || lastCell == null) {
return;
}

int first = firstCell.getIndex();
int last = lastCell.getBoundsInParent().getMaxY() > flow.getHeight()
? lastCell.getIndex() - 1
: lastCell.getIndex();

if (index < first) {
listView.scrollTo(index);
} else if (index >= last) {
listView.scrollTo(index - (last - first));
}
}

public static void main(String[] args) {
launch(args);
}
}
И вот результат:
Изображение

Как видите, для 7 это не удается, поскольку выбранная ячейка всегда должна быть полностью видна. Кто-нибудь может сказать, как это сделать?

Вернуться в «JAVA»