我在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. OutOfMemoryException滾動很多時間
- 3. 在面板中滾動很多圖片
- 4. 問題textfields和滾動視圖
- 5. 控制哪個VBox獲取滾動條
- 6. 很難滾動了滾動在Xcode 6
- 7. textfields上的transform.matrix?
- 8. AngularJS無限滾動,有很多數據
- 9. UIPickerview多個TextFields Xcode
- 10. JavaFX VBox一行上的多個元素
- 11. 動畫滾動很buggy
- 12. 在很多元素上綁定動畫
- 13. 使用jquery nicescroll在移動設備上滾動很慢
- 14. UIAlertViewStyleLoginAndPasswordInput有更多的TextFields?
- 15. scrollIntoView()滾動到很低
- 16. UICollectionView滾動很不穩定
- 17. 爲什麼wrapAll在無限滾動,有很多div?
- 18. ajax請求在滾動速度很快時觸發多次
- 19. VBox上未觸發的Flex鼠標滾輪事件
- 20. Textfields/TextViews不會添加到滾動視圖iOS
- 21. GTK C如何添加滾動窗口到vbox
- 22. 沒有得到可滾動的tabpanel Extjs 4.x與vbox佈局
- 23. Sencha:帶有內置tabpanel的可滾動vbox佈局
- 24. Flex:列表與VBOX類型(平滑)滾動?
- 25. listview在android中滾動很慢
- 26. 滾輪事件發射太頻繁/很多滾動破壞動畫
- 27. 滾動bg不能很好地在鉻上工作
- 28. recyclerview現在可以很好地向上或向下滾動
- 29. VBox動態更改爲HBox
- 30. 如何在j2me中動態創建TextFields?
感謝您的代碼,但它沒有幫助。滾動仍然卡住並顯示TextFields。 – tonimaroni
是滾動是斯圖爾特。這似乎是Android上的ScrollPane與javafxport結合使用的一個基本問題,無論ScrollPane中使用的節點如何。 – jns