JavaFX-ListView在滚动条中单击向下或向上时逐个滚动元素
我有一个包含16项的列表视图。当我使用箭头或默认ListView滚动条的鼠标滚动它时,它会滚动半个项目 我需要的是在单击箭头或鼠标滚动时滚动一个项目,这样列表就不会显示一半的项目。有没有办法做到这一点? 这是我的密码:JavaFX-ListView在滚动条中单击向下或向上时逐个滚动元素,listview,javafx,Listview,Javafx,我有一个包含16项的列表视图。当我使用箭头或默认ListView滚动条的鼠标滚动它时,它会滚动半个项目 我需要的是在单击箭头或鼠标滚动时滚动一个项目,这样列表就不会显示一半的项目。有没有办法做到这一点? 这是我的密码: public void start(Stage primaryStage) throws IOException { ListView<String> lstRequestOpt = new ListView<>(); List<St
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集成。我会继续努力的。代码如下:
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");
}
}
});
}
}
感谢所有帮助我的人。试试这个:
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);
我有一个非常讨厌的方法。不确定这是否适合你。但最终的意图是不要一个接一个地滚动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);
}
});
}
});
}
}
}
这真的很好。但是,当我滚动时,我需要在滚动时保留上一次选择,并且您的评论方式会在滚动时选择一个选项。如果滚动很小,滚动事件也不会触发,这在我的情况下很重要。无论如何,谢谢你。我不确定你是否理解。。。是否要按一个元素滚动列表而不更改选择?是。当滚动时,我唯一感兴趣的是看到元素完整,而不是被减半,但不改变选择。请提供一个例子来说明问题。也就是说:基本上,您可以查找滚动条并将其单位增量设置为nice try+1:-但不可靠至少在fx11:a中不可靠在这个确切的示例中,由于舞台的固定大小,有半行,而不是让场景在其pref.b处出现,其中包含更多项,例如100和pref initial,一切似乎都按预期进行。。。C只有一段时间:有虚假的人工制品f.i.当点击滚动条向上箭头向上滚动时,第一行看起来上面有一些空白-这可能是内部状态混乱和细胞重复使用不完整的结果,但问题太模糊了。@kleopatra,谢谢你的反馈。是的,我也意识到这种方法存在一些问题。因为我使用它的背景是一个完全不同的固定可见行数、固定桌子高度等,它完全适合我的目的。我认为,给出我的意见可能有助于提问者朝着这个方向思考,从而找到更好的解决方案。