JavaFX - Прокрутка ListView по одному элементу при нажатии вниз или вверх на полосе прокрутки - PullRequest
0 голосов
/ 19 марта 2019

У меня есть ListView с 16 элементами. Когда я прокручиваю его (используя стрелки или мышь) стандартной прокрутки ListView, он прокручивает половину элемента.

Что мне нужно, так это прокручивать по одному элементу (при нажатии на стрелки или при прокрутке с помощью мыши), чтобы в списке никогда не отображалось половина элементов. Есть какой-либо способ сделать это? Вот мой код:

public void start(Stage primaryStage) throws IOException {
    ListView<String> lstRequestOpt = new ListView<>();
    List<String> x = new ArrayList<>();
    for(int i = 0; i < 30; i++) {
        x.add("item " + i);
    }
    ObservableList<String> items = FXCollections.observableArrayList(x);
    lstRequestOpt.setItems(items);
    Scene scene = new Scene(lstRequestOpt);
    primaryStage.setScene(scene);
    primaryStage.show();
}

Вот выходное изображение: ListView с половиной элементов

Я пытаюсь добиться того, чтобы элементы отображались полностью, а не как на картинке:

  • При прокрутке
  • При перемещении полосы прокрутки с помощью мыши
  • При нажатии на стрелки на полосе прокрутки

Есть ли способ сделать это?

UPDATE:

Мне удалось создать метод, который будет печатать что-либо, когда используется прокрутка или стрелки, даже если это самая маленькая прокрутка. Теперь мне нужно найти способ установить значение движения в свитке и интегрировать его с ListView. Я буду продолжать работать над этим. Вот код:

for (Node node : lstRequestOpt.lookupAll(".scroll-bar")) {
        if (node instanceof ScrollBar) {
            final ScrollBar bar = (ScrollBar) node;
            bar.valueProperty().addListener(new ChangeListener<Number>() {
                @Override
                public void changed(ObservableValue<? extends Number> value, Number oldValue, Number newValue) {
                    if ((double) oldValue < (double) newValue) {
                        System.out.println("UP");
                    } else {
                        System.out.println("DOWN");
                    }
                }
            });
        }
    }

Спасибо всем, кто мне помогает.

Ответы [ 2 ]

1 голос
/ 20 марта 2019

У меня был очень хакерский путь.Не уверен, подходит ли вам это или нет.Но конечная цель состоит в том, чтобы не прокручивать px на px.

Идея состоит в том, чтобы прослушать свойство value вертикальной полосы прокрутки и установить прокрутку ListView на основе текущего значения полосы прокрутки.Приведенный ниже подход может дать вам некоторые входные данные.Одним из недостатков является то, что мне нужно полагаться на VirtualFlow.

import com.sun.javafx.scene.control.skin.VirtualFlow;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.AccessibleAttribute;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.ScrollBar;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import java.util.ArrayList;
import java.util.List;

public class ListViewScrollDemo  extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        StackPane root = new StackPane();
        Scene sc = new Scene(root, 600, 200);
        stage.setScene(sc);
        stage.show();
        List<String> items = new ArrayList<>();
        for (int i = 1; i < 21; i++) {
            items.add("Item "+i);
        }
        ObservableList<String> itemList = FXCollections.observableArrayList();
        itemList.addAll(items);
        ScrollListView<String> list = new ScrollListView<>();
        list.setItems(itemList);
        root.getChildren().add(list);
    }

    public static void main(String[] args) {
        Application.launch(args);
    }

    class ScrollListView<T> extends ListView<T>{
        boolean firstRender = false;
        public ScrollListView() {
            needsLayoutProperty().addListener((obs,old,needsLayout)->{
                if(!firstRender && !needsLayout){
                    firstRender = true;
                    VirtualFlow<?> virtualFlow = (VirtualFlow<?>) lookup(".virtual-flow");

                    // Keeping vertical scrollBar node reference and tweaking the vertical scroll bar behavior to
                    // scroll by row and not by pixel.
                    ScrollBar vScrollBar = (ScrollBar) queryAccessibleAttribute(AccessibleAttribute.VERTICAL_SCROLLBAR);
                    vScrollBar.valueProperty().addListener((obs1, oldVal1, newVal) -> {
                        int visibleRowCount = virtualFlow.getLastVisibleCell().getIndex()-virtualFlow.getFirstVisibleCell().getIndex();
                        final double scrollVal = newVal.doubleValue();
                        final int size = getItems().size();
                        if (scrollVal < 1.0) {
                            final int virtualRowCount = size - visibleRowCount;
                            final double eachRowBuff = 1d / virtualRowCount;
                            for (int index = 0; index < virtualRowCount; index++) {
                                final double start = eachRowBuff * index;
                                final double end = start + eachRowBuff;
                                if (start <= scrollVal && scrollVal < end) {
                                    scrollTo(index);
                                    vScrollBar.setValue(start);
                                    break;
                                }
                            }
                        } else {
                            scrollTo(size - 1);
                        }
                    });
                }
            });
        }
    }
}
0 голосов
/ 20 марта 2019

попробуйте это:

  ListView listView = new ListView();
    listView.setItems(listConetnt);

    EventHandler onePositionScrollEvent = (EventHandler<ScrollEvent>) event -> {
        int scrollIndex = 0;

        if (event.getDeltaY() > 0) {
            scrollIndex = listView.getSelectionModel().getSelectedIndex() - 1;
        } else {
            scrollIndex = listView.getSelectionModel().getSelectedIndex() + 1;
        }

        listView.getSelectionModel().select(scrollIndex);
    };

    listView.setOnScroll(onePositionScrollEvent);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...