我在使方法setOnKeyPressed与MouseEvent.MOUSE_ENTERED一起工作时遇到困难。我的目标是让setOnKeyPressed事件仅在鼠标悬停在舞台上的节点(更精确地为Shape)上时运行,但是即使鼠标不在形状上,也会调用setOnKeyPressed方法。
这是我创建形状的方法:

Circle circle= new Figura().createCircle(40, 50, 50, Color.BLACK);
root.getChildren().add(circle);
circle.setCenterX(stage.getWidth()/2);
circle.setCenterY(stage.getHeight()/2);
addMouseScrolling(circle);
addKeyPressed(circle); // this handle the 'KeyPressed' and 'Mouse_Entered' events
circle.requestFocus();


这是我处理mouseEvent + setOnKeyPressed内容的方式:

public void addKeyPressed(Node node) {
   node.addEventFilter(MouseEvent.MOUSE_ENTERED, e -> {
       node.setOnKeyPressed(t -> {

           if (t.getCode()==KeyCode.R) System.out.println("Key "R" pressed!");
       });
    });


}

就像我说过的,我只想将setOnKeyPressed方法仅在鼠标悬停在节点上时调用,现在我总是调用它,不仅在鼠标悬停在节点上时:我创建了一个圆(创建它不会使setonkeypressed工作),然后单击它,然后从现在开始按控制台上的“已按下键“ R””打印“ r”。我希望我能清楚地解释我的问题。
提前致谢。

最佳答案

最简单的方法是使用KeyEvent.KEY_PRESSED处理程序,并将if (node.isHover) { ... }添加到您的处理程序中:

public void addKeyPressed(Node node) {
    node.addEventHandler(KeyEvent.KEY_PRESSED, e -> {
        if (node.isHover()) {
            if (e.getCode()==KeyCode.R) System.out.println("Key "R" pressed!");
        }
    });
}


您还可以通过添加和删除键事件处理程序来执行此操作,如下所示:

public void addKeyPressed(Node node) {
    EventHandler<KeyEvent> keyHandler = e -> {
        if (e.getCode() == KeyCode.R) {
            System.out.println("Key \"R\" pressed!");
        }
    } ;
    node.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> {
        node.addEventHandler(KeyEvent.KEY_PRESSED, keyHandler);
    });
    node.addEventHandler(MouseEvent.MOUSE_EXITED, e -> {
        node.removeEventHandler(KeyEvent.KEY_PRESSED, keyHandler);
    });
}


此版本允许您在鼠标进入节点时自动请求将焦点集中在该节点上。只需修改鼠标输入的处理程序即可:

    node.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> {
        node.addEventHandler(KeyEvent.KEY_PRESSED, keyHandler);
        node.requestFocus();
    });

10-04 10:46