连接控制器与 Scene Builder 事件

Connection controller with Scene Builider events

如何使用 Scene Builder 连接键盘/鼠标等事件?? 我的代码看起来像:

@FXML 
    public void onKeyPressed() {
          group.getScene().setOnKeyPressed(event -> {
              double change = 10.0;
              if(event.isShiftDown()) { change = 50.0; }
              KeyCode keycode = event.getCode();
              if(keycode == KeyCode.W) { perspectiveCamera.setTranslateZ(perspectiveCamera.getTranslateZ() + change); }
              if(keycode == KeyCode.S) { perspectiveCamera.setTranslateZ(perspectiveCamera.getTranslateZ() - change); }
              if(keycode == KeyCode.A) { perspectiveCamera.setTranslateX(perspectiveCamera.getTranslateX() - change); }
              if(keycode == KeyCode.D) { perspectiveCamera.setTranslateX(perspectiveCamera.getTranslateX() + change); }
          });    
    }
    @FXML
    public void onMousePressed() {
        group.getScene().setOnMousePressed((MouseEvent me) -> {
             mousePosX = me.getSceneX();
             mousePosY = me.getSceneY();
             mouseOldX = me.getSceneX();
             mouseOldY = me.getSceneY();
         });
    }
    @FXML
    public void onMouseDragged() {
        group.getScene().setOnMouseDragged((MouseEvent me) -> {
            mouseOldX = mousePosX;
            mouseOldY = mousePosY;
            mousePosX = me.getSceneX();
            mousePosY = me.getSceneY();
            mouseDeltaX = (mousePosX - mouseOldX);
            mouseDeltaY = (mousePosY - mouseOldY);

            double modifier = 10.0;
            double modifierFactor = 0.1;

            if (me.isControlDown()) {
                modifier = 0.1;
            }
            if (me.isShiftDown()) {
                modifier = 50.0;
            }
            if (me.isPrimaryButtonDown()) {
                cameraTransformer.ry.setAngle(((cameraTransformer.ry.getAngle() + mouseDeltaX * modifierFactor * modifier * 2.0) % 360 + 540) % 360 - 180);  // +
                cameraTransformer.rx.setAngle(((cameraTransformer.rx.getAngle() - mouseDeltaY * modifierFactor * modifier * 2.0) % 360 + 540) % 360 - 180);  // -
            } else if (me.isSecondaryButtonDown()) {
                double z = perspectiveCamera.getTranslateZ();
                double newZ = z + mouseDeltaX * modifierFactor * modifier;
                perspectiveCamera.setTranslateZ(newZ);
            } else if (me.isMiddleButtonDown()) {
                cameraTransformer.t.setX(cameraTransformer.t.getX() + mouseDeltaX * modifierFactor * modifier * 0.3);  // -
                cameraTransformer.t.setY(cameraTransformer.t.getY() + mouseDeltaY * modifierFactor * modifier * 0.3);  // -
            }
        });
    }

场景生成器面板:

我通常总是以相同的方式进行操作并且它有效,但现在使用此面板却不起作用。我在哪里做错了?

关于鼠标事件,在anchorpane中设置:

<AnchorPane onMouseDragged="#onMouseDragged" onMousePressed="#onMousePressed" ...>
   <children>
      <Group fx:id="group" />
   </children>
</AnchorPane>

现在在您的控制器中直接传递事件:

@FXML
private void onMousePressed(MouseEvent me) {
    mousePosX = me.getSceneX();
    mousePosY = me.getSceneY();
    mouseOldX = me.getSceneX();
    mouseOldY = me.getSceneY();
}

@FXML
private void onMouseDragged(MouseEvent me) {
    mouseOldX = mousePosX;
    mouseOldY = mousePosY;
    mousePosX = me.getSceneX();
    mousePosY = me.getSceneY();
    ...
}

至于按键事件,好像场景接受了这个事件并消费了它,所以你需要将它从场景传播到控制器:

@Override
public void start(Stage stage) throws Exception {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("Window3DSceneView.fxml"));
    Parent root = loader.load();
    Window3DController controller = loader.getController();

    Scene scene = new Scene(root, 1200, 800, true, SceneAntialiasing.BALANCED);
    scene.setOnKeyPressed(e -> controller.onKeyPressed(e));
    ...
}

现在在您的控制器中:

 public void onKeyPressed(KeyEvent event) {
      double change = 10.0;
      if(event.isShiftDown()) { change = 50.0; }
      KeyCode keycode = event.getCode();
      ...
 }