JavaFX:滚动时,如何聚焦并选择具有ListView的下一个单元格?

JavaFX:滚动时,如何聚焦并选择具有ListView的下一个单元格?,listview,scroll,javafx-2,scrollbar,Listview,Scroll,Javafx 2,Scrollbar,我有一个充满单元格的列表视图,我想滚动到下一个单元格,使其聚焦并选中 我的代码可以向下滚动,但滚动条会走远 如何减小每个单元格的滚动大小,以便查看聚焦单元格?有没有更好的方法来实现这一点 这是我的密码: documentListView.scrollTo(0); documentListView.getSelectionModel().select(0); int indexSize = documentListView.getItems().size(); for (Node node :

我有一个充满单元格的
列表视图
,我想滚动到下一个单元格,使其聚焦并选中

我的代码可以向下滚动,但滚动条会走远

如何减小每个单元格的滚动大小,以便查看聚焦单元格?有没有更好的方法来实现这一点

这是我的密码:

documentListView.scrollTo(0);
documentListView.getSelectionModel().select(0);

int indexSize = documentListView.getItems().size();

for (Node node : documentListView.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) {
                int selectedIndex = documentListView.getSelectionModel().getSelectedIndex();

                if(selectedIndex <= indexSize && listScrollDown(oldValue.floatValue(), newValue.floatValue())) {
                    selectedIndex++;
                    documentListView.scrollTo(selectedIndex);
                    documentListView.getFocusModel().focus(selectedIndex);
                    documentListView.getSelectionModel().select(selectedIndex);
                } 
            }
        });
    }
}
documentListView.scrollTo(0);
documentListView.getSelectionModel().select(0);
int indexSize=documentListView.getItems().size();
对于(节点:documentListView.lookupAll(“.scroll bar”)){
if(滚动条的节点实例){
最终滚动条=(滚动条)节点;
bar.valueProperty().addListener(新的ChangeListener()){
@凌驾

更改公众假期(ObservalEvalue我不得不在一些定制硬件中处理同样的需求。我最终使用
TableView
虚拟流
来处理这项工作。你必须控制滚动以及选择,但它最终为我提供了选择所需的细粒度控制。下面是一个简单的定制
TableView
应该满足您的要求

package custom.javafx.controls;

import com.sun.javafx.scene.control.skin.TableViewSkin;
import com.sun.javafx.scene.control.skin.VirtualFlow;
import javafx.beans.value.*;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.control.Skin;
import javafx.scene.control.TableView;
import javafx.scene.input.ScrollEvent;

public class CustomTableView<T> extends TableView<T>
{
    private VirtualFlow flow = null;

    public CustomTableView()
    {
        super();

        /* Navigation listeners */
        skinProperty().addListener(skinPropertyChangeListener);
        getSelectionModel().selectedIndexProperty().addListener(selectedIndexChangeListener);
        addEventFilter(ScrollEvent.SCROLL, scrollEventFilter);  
    }

    /* You need this to prevent NPE's when trying to use the skin */
    private ChangeListener<Skin> skinPropertyChangeListener =
            new ChangeListener<Skin>()
    {
        @Override
        public void changed(ObservableValue<? extends Skin> ov,
            Skin t, Skin t1)
        {
            if (t1 == null) { return; }
            TableViewSkin skin = (TableViewSkin)t1;
            ObservableList<Node> kids = skin.getChildrenUnmodifiable();

            if (kids != null && !kids.isEmpty())
            {
                flow = (VirtualFlow)kids.get(1);
            }
        }
    };

    /* This handles the scrolling to ensure that a selection is visible */
    private ChangeListener<Number> selectedIndexChangeListener =
            new ChangeListener<Number>()
    {
        @Override
        public void changed(ObservableValue<? extends Number> ov,
            Number t, Number t1)
        {
            if (t1 == null || flow == null || t1.intValue() < 0) { return; }
            if (flow.getFirstVisibleCell() == null) { return; }

            int selected = t1.intValue();
            int first = flow.getFirstVisibleCell().getIndex();
            int last = flow.getLastVisibleCell().getIndex();

            if (selected <= first || selected >= last)
            {
                flow.show(selected);
            }
        }
    };

    /* Overrides the ScrollEvent handler to force selection rather than scrolling */
    private EventHandler<ScrollEvent> scrollEventFilter =
            new EventHandler<ScrollEvent>()
    {
        @Override
        public void handle(ScrollEvent t)
        {
            if (t.getDeltaY() < 0)
            {
                getSelectionModel().selectNext();
            }
            else
            {
                getSelectionModel().selectPrevious();
            }

            t.consume();
        }
    };
}
package custom.javafx.controls;
导入com.sun.javafx.scene.control.skin.TableViewSkin;
导入com.sun.javafx.scene.control.skin.VirtualFlow;
导入javafx.beans.value.*;
导入javafx.collections.ObservableList;
导入javafx.event.EventHandler;
导入javafx.scene.Node;
导入javafx.scene.control.Skin;
导入javafx.scene.control.TableView;
导入javafx.scene.input.ScrollEvent;
公共类CustomTableView扩展了TableView
{
私有虚拟流流量=null;
公共CustomTableView()
{
超级();
/*导航侦听器*/
skinProperty().addListener(skinPropertyChangeListener);
getSelectionModel().selectedIndexProperty().addListener(selectedIndexChangeListener);
addEventFilter(ScrollEvent.SCROLL,scrollEventFilter);
}
/*当你尝试使用皮肤时,你需要这个来防止NPE*/
私有ChangeListener skinPropertyChangeListener=
新的ChangeListener()
{
@凌驾

public void已更改(observeValueI刚更改了此行:flow=(VirtualFlow)kids.get(1);类似于:flow=(VirtualFlow)kids.get(0);