我在Scrollpane中有很多VBox中的Textfields。当滚动和触摸文本框时,它只是抓住焦点。所以平滑滚动是不可能的。我怎么能很好地滚动,没有任何文本域的不必要的焦点。我是否需要在滚动时消耗文本字段上的事件?在VBox上滚动很多Textfields
1
A
回答
0
这里是我使用为目的的一类你描述:
public class MouseClickedFilter{
private final Node observableNode;
private BooleanProperty scrolling = new ReadOnlyBooleanWrapper(false);
private EventHandler<? super MouseEvent> dragDetectedFilter = e -> scrolling.set(true);
private EventHandler<? super MouseEvent> mouseExitedHandler = e -> scrolling.set(false);
private EventHandler<? super MouseEvent> mouseClickedFilter = evt ->
{
if (scrolling.get()) {
evt.consume();
scrolling.set(false);
}
};
private boolean listenersEnabled;
public MouseClickedFilter(Node observableNode) {
this.observableNode = observableNode;
}
public void activate() {
if (!listenersEnabled) {
observableNode.addEventFilter(MouseEvent.DRAG_DETECTED, dragDetectedFilter);
observableNode.addEventHandler(MouseEvent.MOUSE_EXITED, mouseExitedHandler);
observableNode.addEventFilter(MouseEvent.MOUSE_CLICKED, mouseClickedFilter);
}
}
public void deactivate() {
if (listenersEnabled) {
observableNode.removeEventFilter(MouseEvent.DRAG_DETECTED, dragDetectedFilter);
observableNode.removeEventHandler(MouseEvent.MOUSE_EXITED, mouseExitedHandler);
observableNode.removeEventFilter(MouseEvent.MOUSE_CLICKED, mouseClickedFilter);
}
}
public final ReadOnlyBooleanProperty scrollingProperty() {
return scrolling;
}
public final boolean isScrolling() {
return scrolling.get();
}
}
ObservableNode
是包含文本框
0
这是情况下,你要在滚动一个可能的解决方案您ScrollPane
长长的文本框列表,不让它们占据焦点,直到完全停止滚动,并且显然希望选择其中一个文本框。
它基于一个自定义的“按住”事件,受此启发question。
想法是将HBOX中的TextField
控件捆绑在一起,并禁用使用容器的鼠标透明属性访问控件。
然后,无论何时点击容器,如果按足够长的时间,容器就可以访问控制器,键盘将显示出来。否则,您将继续滚动,但不显示键盘。
我将仅在iOS上使用此question中提及的KeyboardService
。
public class BasicView extends View {
public BasicView(String name) {
super(name);
setTop(new Button("Button"));
VBox controls = new VBox(15.0);
controls.setAlignment(Pos.CENTER);
ScrollPane pane = new ScrollPane(controls);
controls.prefWidthProperty().bind(pane.widthProperty().subtract(20));
for (int i = 0; i < 100; i++) {
final Label label = new Label("TextField " + (i + 1));
final TextField textField1 = new TextField();
HBox.setHgrow(textField1, Priority.ALWAYS);
HBox box = new HBox(10, label, textField1);
box.setMouseTransparent(true);
box.setAlignment(Pos.CENTER_LEFT);
box.setPadding(new Insets(5));
controls.getChildren().add(box);
}
addPressAndHoldHandler(controls, Duration.millis(300), eStart -> {
for (Node box : controls.getChildren()) {
box.setMouseTransparent(true);
}
}, eEnd -> {
for (Node box : controls.getChildren()) {
if (box.localToScene(box.getBoundsInLocal()).contains(eEnd.getSceneX(), eEnd.getSceneY())) {
box.setMouseTransparent(false);
((HBox) box).getChildren().get(1).requestFocus();
break;
}
}
});
setCenter(pane);
// iOS only
Services.get(KeyboardService.class).ifPresent(keyboard -> {
keyboard.visibleHeightProperty().addListener((obs, ov, nv) -> {
if (nv.doubleValue() > 0) {
for (Node box : controls.getChildren()) {
Node n1 = ((HBox) box).getChildren().get(1);
if (n1.isFocused()) {
double h = getScene().getHeight() - n1.localToScene(n1.getBoundsInLocal()).getMaxY();
setTranslateY(-nv.doubleValue() + h);
break;
}
}
} else {
setTranslateY(0);
}
});
});
}
@Override
protected void updateAppBar(AppBar appBar) {
appBar.setNavIcon(MaterialDesignIcon.MENU.button(e -> System.out.println("Menu")));
appBar.setTitleText("Scrolling over TextFields");
}
private void addPressAndHoldHandler(Node node, Duration holdTime,
EventHandler<MouseEvent> handlerStart, EventHandler<MouseEvent> handlerEnd) {
class Wrapper<T> {
T content;
}
Wrapper<MouseEvent> eventWrapper = new Wrapper<>();
PauseTransition holdTimer = new PauseTransition(holdTime);
holdTimer.setOnFinished(event -> handlerEnd.handle(eventWrapper.content));
node.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> {
handlerStart.handle(event);
eventWrapper.content = event;
holdTimer.playFromStart();
});
node.addEventHandler(MouseEvent.MOUSE_RELEASED, event -> holdTimer.stop());
node.addEventHandler(MouseEvent.DRAG_DETECTED, event -> holdTimer.stop());
}
}
请注意,当您显示视图时,我已在顶部添加了一个按钮以使焦点位于第一位。
每当您点击/点击controls
VBox时,它会将所有框设置为透明:box.setMouseTransparent(true);
,并启动PauseTransition
。
如果在300毫秒之前有鼠标释放或鼠标拖动(这可以在您方便时更改),则转换将停止。否则,在300 ms后,它会将框设置为box.setMouseTransparent(false);
,并将焦点设置在TextField上,此时键盘将显示出来。
相关问题
- 1. extjs滚动条在vbox内部丢失
- 2. 在面板中滚动很多图片
- 3. 问题textfields和滚动视图
- 4. 控制哪个VBox获取滚动条
- 5. 很难滚动了滚动在Xcode 6
- 6. textfields上的transform.matrix?
- 7. JavaFX VBox一行上的多个元素
- 8. 在很多元素上绑定动画
- 9. UICollectionView滚动很不稳定
- 10. scrollIntoView()滚动到很低
- 11. 为什么wrapAll在无限滚动,有很多div?
- 12. VBox上未触发的Flex鼠标滚轮事件
- 13. Flex:列表与VBOX类型(平滑)滚动?
- 14. listview在android中滚动很慢
- 15. 滚轮事件发射太频繁/很多滚动破坏动画
- 16. 滚动bg不能很好地在铬上工作
- 17. VBox动态更改为HBox
- 18. 在动态表格中获取textfields值
- 19. 如何在Java中动态访问textfields?
- 20. PageViewController滚动错误(在滚动条上)
- 21. GCD在滚动tableview上滚动数据
- 22. 在滚动条上滚动100vh部分
- 23. 键盘在textfields的方式如何向上移动视图
- 24. 在UIPickerView上滚动动画
- 25. 当物品靠近顶部或底部边缘时,如何自动滚动VBox?
- 26. jquery无限滚动 - 在div上不滚动滚动条
- 27. Log4j RollingFileAppender在Linux上滚动,但在Windows上不滚动
- 28. 向上滚动时向上滚动listview
- 29. Android listview滚动不平滑,当我加载很多位图时
- 30. RecyclerView不会向下滚动,如果有很多项目
感谢您的代码,但它没有帮助。滚动仍然卡住并显示TextFields。 – tonimaroni
是滚动是斯图尔特。这似乎是Android上的ScrollPane与javafxport结合使用的一个基本问题,无论ScrollPane中使用的节点如何。 – jns