这是非常基本的先生,当您使用 Touchscroll 滚动时,您肯定会触摸可滚动的 Pane 区域,并且通过触摸 Pane requestFocus(),因此您的 TextField 将失去焦点。
所以要解决它,如果您通过使用该窗格或节点的滚动侦听器检测到触摸,或者转到 setOnTouchStationary() 或 setOnTouchReleased(),则将焦点发送回您的 TextField,以帮助调整您的可见性键盘而不是躺在TextField 的焦点上。
编辑
试试这个
Node lastFocusedNode =null; // lastly known node to have focus
//now every node or child in your ScrollPane or Scrollable parent
//that you care about will have a focusable listener-including
// your textfield
textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(
ObservableValue<? extends Boolean> observable,
Boolean oldValue, Boolean newValue) {
if(!newValue){//if they loose focus
lastFocusedNode = textField;
//if they loose focus attach them to lastFocusedNode
}
}
});
//the above saves you iterations
然后,当您的 ScrollPane/scrollable 节点接收焦点时,您将它们设置为 lastFocusedNode,因为它只是允许滚动。
sp.focusedProperty().addListener(new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
if (lastFocusedNode != null) {
lastFocusedNode.requestFocus();
}
}
});
以上假设您的 ScrollPane 除了滚动之外不会做任何消耗......
如果您的 ScrollPane/scrollable 父级不采用该假设,那么
您采用这种方法 - 检测用户在触摸 Scrollable Node 的内容区域后何时滚动 - 这仅在用户在触摸后尝试滚动时才有效。
//approach loaded
final InvalidationListener lis = new InvalidationListener() {
@Override
public void invalidated(Observable observable) {
//here it is changing
if(sp.isFocused())
lastFocusedNode.requestFocus();//take the focus away
}
};
使用上述失效监听器,您将其设置在 hvalueProperty() 和 vvalueProperty() 或您的 ScrollPane - 您使用的是哪个 Scrollable 父级?
sp.hvalueProperty().addListener(lis);
sp.vvalueProperty().addListener(lis);
那么你就完成了。以上任何一种解决方案都会导致没问题
编辑 2
据我所知,TouchEvent 适用于支持触控的计算机,所以也许可以使用MouseEvent,您可以检测到Pane.setOnMousePressed(); 等等等
希望对你有帮助