【问题标题】:JavaFX key press not captured未捕获 JavaFX 按键
【发布时间】:2015-07-09 14:09:57
【问题描述】:

我正在尝试捕获按键事件(向上和向下翻页),但根本没有收到任何按键事件。以下是相关代码: 构造函数:

private MainLayout() {
    imageView = new ImageView();
    root = new StackPane();

    root.getChildren().add(imageView);
    root.setFocusTraversable(true); //no effect
    //root.requestFocus(); //also no effect
    registerEvents();

}

关于焦点的两条线都没有效果。堆栈窗格直接添加到场景中。 除了 Scene->StackPane->ImageView 没有其他节点。 我能够捕捉现场的关键事件,但我需要在堆栈窗格中捕捉它们

这里是registerEvents(),所有其他事件都被很好地捕获!:

private void registerEvents() {
    OnScroll onScroll = new OnScroll();
    root.setOnScroll(onScroll);
    OnResize onResize = new OnResize();
    root.heightProperty().addListener(onResize);
    root.widthProperty().addListener(onResize);
    OnMouseDown onMouseDown = new OnMouseDown();
    root.setOnMousePressed(onMouseDown);
    root.setOnMouseReleased((event) -> fitImage());
    root.setOnDragOver((event) -> dragOver(event));
    root.setOnDragDropped((event) -> dropFile(event));
    root.setOnKeyPressed((event) -> {
        LOG.debug("Key captured.");
        if(event.getCode() == KeyCode.PAGE_UP){
            imageView.setImage(ip.prev());
            event.consume();
        } else if(event.getCode() == KeyCode.PAGE_DOWN){
            imageView.setImage(ip.next());
            event.consume();
        }
        if(event.isConsumed()){
            fitImage();
        }
    });

我没有看到日志输出,也没有捕获断点。那么如何正确捕捉和处理关键事件呢?

【问题讨论】:

  • 考虑添加#java 标签,它会帮助您获得更多关注,并可能获得更多答案;-)

标签: java events javafx keyevent


【解决方案1】:

同时感谢this answer,我找到了解决方案。诀窍是 setFocusTraversable(true) 在 ImageView (堆栈窗格的子级)上。这是工作代码:

@Inject
private MainLayout(ImageProvider ip) {
    this.ip = ip;

    imageView = new ImageView();
    imageView.setFocusTraversable(true);
    imageView.requestFocus();

    root = new StackPane();

    root.getChildren().add(imageView);
    registerEvents();
}

【讨论】:

    【解决方案2】:

    我不知道这个答案是否会让你满意,但我会将处理事件从这个类移到你初始化场景的类,并将事件附加到场景本身(因为 StackPane 在方式,场景)。我猜想,由于代码中的构造函数是私有的,因此您正在通过另一个类的公共静态方法实例化该类。

    public class MainClass extends Application {
       private Scene scene = new Scene(MainLayout.getMainLayout());
    
       @Override
       public void start(Stage primaryStage) throws Exception {
            registerEvents();        
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
       private void registerEvents() {
            OnScroll onScroll = new OnScroll();
            scene.setOnScroll(onScroll);
            OnResize onResize = new OnResize();
            scene.heightProperty().addListener(onResize);
            scene.widthProperty().addListener(onResize);
            OnMouseDown onMouseDown = new OnMouseDown();
            scene.setOnMousePressed(onMouseDown);
            scene.setOnMouseReleased((event) -> fitImage());
            scene.setOnDragOver((event) -> dragOver(event));
            scene.setOnDragDropped((event) -> dropFile(event));
            scene.setOnKeyPressed((event) -> {
                LOG.debug("Key captured.");
                if (event.getCode() == KeyCode.PAGE_UP) {
                    imageView.setImage(ip.prev());
                    event.consume();
                } else if (event.getCode() == KeyCode.PAGE_DOWN) {
                    imageView.setImage(ip.next());
                    event.consume();
                }
                if (event.isConsumed()) {
                    fitImage();
                }
            });
        }
    }
    

    或者,如果您想将处理事件的代码保留在 MainLayout 类中,请考虑将 registerEvents 设为接受 Scene 作为参数的公共(或本地包,具体取决于您的设计)方法。

    【讨论】:

    • 谢谢,但我确实想在 MainLayout 中保留所有事件处理。私有构造函数是由于使用了依赖注入(我在构造函数上省略了@Inject)。
    猜你喜欢
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多