如何解决如何覆盖 ScrollPane 的默认箭头键行为
我希望 ScrollPane
中的箭头键以默认方式以外的方式工作。在 Keypressed
上的 ScrollPane
处理程序中使用箭头键不会阻止 ScrollPane
处理它们。有什么有效的方法吗?
在示例程序中,
- 键入
h
或向左箭头以按预期将矩形在网格上向左移动。 - 键入
l
或向右箭头以按预期将矩形在网格上向右移动。
图 1. 开始
图 2. 开始,然后 h
键(矩形在网格上向左移动)
图。 3.开始,然后向左箭头键(rect在网格上向左移动,ScrollPane滑块向左移动了不需要的移动)
注意事项:
-
KeyClicked
和keyreleased
显然无关。 - 一种解决方法可能是请求将注意力集中在 rect 上,但这会带来不必要的并发症。
- 另一种解决方法是关注包含的
Pane
。 - 我喜欢操作系统突出显示
ScrollPane
的边框,指示键盘焦点。 - 专注于包含的
Pane
可防止键盘焦点突出显示。 - 覆盖箭头键的默认
ScrollPane
行为对我的应用来说不是问题。 - StackOverflow 上的相关问题并不完全相同。
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class ScrollPaneArrowKeys extends Application {
public static void main(String[] args) { launch(args); }
static Rectangle rect;
static ScrollPane sp;
@Override
public void start(Stage stage) {
rect = new Rectangle (100,50);
var pane = new Pane (rect);
sp = new ScrollPane(pane);
var scene = new Scene (sp);
rect.setFill(Color.PALEGREEN);
pane.setMinWidth (600);
pane.setMinHeight(150);
pane.setStyle(grid);
sp.setMinWidth (300);
sp.setMinHeight(170);
sp.setHvalue(0.5);
sp.setonKeypressed(ScrollPaneArrowKeys::onKeypressed);
sp.requestFocus();
reset();
stage.setScene(scene);
stage.show();
}
private static void onKeypressed(KeyEvent e) {
switch (e.getCode()) {
case H:
case LEFT: rect.setX(rect.getX() - 10); break;
case L:
case RIGHT: rect.setX(rect.getX() + 10); break;
case ESCAPE: reset(); break;
default: break;
}
e.consume();
}
private static void reset() {
rect.setX(250);
rect.setY( 50);
sp.setHvalue(0.5);
}
String grid = """
-fx-background-color: white,linear-gradient(from 0px 0px to 10px 0px,repeat,#d8f0f8 6.25%,transparent 6.25%),linear-gradient(from 0px 0px to 50px 0px,#b0e0e8 1.25%,transparent 1.25%),linear-gradient(from 0px 0px to 0px 10px,linear-gradient(from 0px 0px to 0px 50px,transparent 1.25%);
""";
}
解决方法
如果要覆盖滚动窗格的默认键处理,可以通过注册事件过滤器(而不是添加另一个事件处理程序)来实现。您可以在 e 中阅读有关此内容的信息。 G。这篇文章:JavaFX: What is the difference between EventHandler and EventFilter?
考虑到用户体验,您可能希望添加另一种滚动可能性(例如 CTRL
+ LEFT
等)。这是一个工作示例(大部分取自您的代码):
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class ScrollPaneArrowKeys extends Application {
private final Rectangle rect = new Rectangle(100,50);
private final Pane pane = new Pane(rect);
private final ScrollPane sp = new ScrollPane(pane);
private final Scene scene = new Scene(sp);
@Override
public void start(Stage stage) {
// Register an Event Filter to override the default behaviour:
sp.addEventFilter(KeyEvent.KEY_PRESSED,e -> {
e.consume(); // prevent default key handling
// Allow the user to scroll horizontally with the control key:
if (e.isControlDown())
switch (e.getCode()) {
case LEFT -> sp.setHvalue(sp.getHvalue() - .1);
case RIGHT -> sp.setHvalue(sp.getHvalue() + .1);
}
else
// Move they rectangle only:
switch (e.getCode()) {
case H,LEFT -> rect.setX(rect.getX() - 10);
case L,RIGHT -> rect.setX(rect.getX() + 10);
case ESCAPE -> resetRectPosition();
}
});
initStyling();
resetRectPosition();
stage.setScene(scene);
stage.show();
sp.requestFocus();
}
private void initStyling() {
rect.setFill(Color.PALEGREEN);
pane.setMinWidth(600);
pane.setMinHeight(150);
pane.setStyle("""
-fx-background-color: white,linear-gradient(from 0px 0px to 10px 0px,repeat,#d8f0f8 6.25%,transparent 6.25%),linear-gradient(from 0px 0px to 50px 0px,#b0e0e8 1.25%,transparent 1.25%),linear-gradient(from 0px 0px to 0px 10px,linear-gradient(from 0px 0px to 0px 50px,transparent 1.25%);
""");
sp.setMinWidth(300);
sp.setMinHeight(170);
sp.setHvalue(0.5);
}
private void resetRectPosition() {
rect.setX(250);
rect.setY(50);
sp.setHvalue(0.5);
}
public static void main(String[] args) {
launch(args);
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。