JAVAFX-如何在H box中包含的一个带有其他窗格的键盘中焦点键盘输入



以下图片中描述了情况:在此处输入图像描述

这是一个简单的游戏,我需要在键盘上使用"←"或"→"以移动玩家的砖块,但是当我这样做时,应用程序的焦点只是将其焦点移至Levelpane或Infopane,有什么方法可以明确仅允许Game -Pane接收键盘输入,并且仅当我使用鼠标并单击它时,Level Pane才会集中精力?

下面的Javafx代码:

public void start(Stage primaryStage) throws Exception{
    FXMLLoader loader = new FXMLLoader(getClass().getResource("Game.fxml"));
    Parent page = loader.load();
    Scene scene = new Scene(page);
    Pane levelPane = (Pane)loader.getNamespace().get("levelPane");
    Pane gamePane = (Pane)loader.getNamespace().get("gamePane");
    Pane infoPane = (Pane)loader.getNamespace().get("infoPane");
    Button lv1 = (Button)loader.getNamespace().get("level1");
    Button lv2 = (Button)loader.getNamespace().get("level2");
    Button lv3 = (Button)loader.getNamespace().get("level3");
    Button lv4 = (Button)loader.getNamespace().get("level4");
    Button lv5 = (Button)loader.getNamespace().get("level5");
    Label info = (Label)loader.getNamespace().get("info");

    levelPane.setFocusTraversable(false);
    infoPane.setFocusTraversable(false);
    //gamePane.setFocusTraversable(true);
    gamePane.requestFocus();

    Circle ball = new Circle(10, Color.CADETBLUE);
    ball.relocate(5, 5);
    Rectangle playerBrick = new Rectangle(Data.PLAYER_BRICK_LENGTH,Data.PLAYER_BRICK_WEIGTH,Color.BLACK);
    playerBrick.setArcWidth(20);
    playerBrick.setArcHeight(20);
    playerBrick.setX(150);
    playerBrick.setY(350);
    ArryList<Rectangle> breakableBricks = new ArryList<Rectangle>();

    for (int i = 0; i < Data.BRICK_COUNT ; i++){
        breakableBricks.add(new Rectangle(Data.B_B_LENGTH,Data.B_B_WEIGTH,Color.RED));
        breakableBricks[i].setArcWidth(20);
        breakableBricks[i].setArcHeight(20);
        if(i%5 == 0){
            pixelCountY += Data.B_B_WEIGTH + 10;
        }
        playerBrick.setX(pixelCountX);
        playerBrick.setY(pixelCountY);
        pixelCountX += Data.B_B_LENGTH + 10;
    }
    gamePane.getChildren().add(ball);
    gamePane.getChildren().add(playerBrick);
    gamePane.setBorder(new Border(new BorderStroke(Color.BLACK, BorderStrokeStyle.SOLID, CornerRadii.EMPTY, BorderWidths.DEFAULT)));
    gamePane.setOnKeyPressed(new EventHandler<KeyEvent>(){
        @Override
        public void handle(KeyEvent event){
            switch (event.getCode()){               
                case LEFT: goLeft = true;break;
                case RIGHT: goRight = true;break;
            }
        }
    });
    gamePane.setOnKeyReleased(new EventHandler<KeyEvent>(){
        @Override
        public void handle(KeyEvent event){
            switch (event.getCode()){
                case LEFT: goLeft = false;break;
                case RIGHT: goRight = false;break;
            }
        }
    });

    primaryStage.setScene(scene);
    primaryStage.show();    

    Timeline timeline = new Timeline(new KeyFrame(Duration.millis(20),new EventHandler<ActionEvent>() {
        double dx = Data.HORIZONTAL_VELOCITY; //Step on x or velocity
        double dy = Data.VERTICAL_VELOCITY; //Step on y
        double playerBrickSpeed = Data.PLAYER_BRICK_S;//Player Brick moving speed
        @Override
        public void handle(ActionEvent t) {
            //move the ball
            ball.setLayoutX(ball.getLayoutX() + dx);
            ball.setLayoutY(ball.getLayoutY() + dy);
            Bounds bounds = gamePane.getBoundsInLocal();
            Bounds brickB = playerBrick.getLayoutBounds();
            //If the ball reaches the left or right border make the step negative
            if(ball.getLayoutX() <= (bounds.getMinX() + ball.getRadius()) ||
                    ball.getLayoutX() >= (bounds.getMaxX() - ball.getRadius()) ){
                dx = -dx;
            }
            //If the ball reeaches the brick's wall makes the ball bounce
            if(ball.getLayoutY() < brickB.getMaxY() & ball.getLayoutY() > brickB.getMinY()){
                if(ball.getLayoutX() > brickB.getMinX() - Data.HORIZONTAL_VELOCITY & ball.getLayoutX() < brickB.getMinX() + Data.HORIZONTAL_VELOCITY  || ball.getLayoutX() > brickB.getMaxX() - Data.HORIZONTAL_VELOCITY & ball.getLayoutX() < brickB.getMaxX() + Data.HORIZONTAL_VELOCITY ){
                    dx = -dx;
                }
            }
            if(ball.getLayoutX() > brickB.getMinX() & ball.getLayoutX() < brickB.getMaxX()){
                if(ball.getLayoutY() < brickB.getMaxY() + Data.VERTICAL_VELOCITY & ball.getLayoutY() > brickB.getMaxY() - Data.VERTICAL_VELOCITY || ball.getLayoutY() > brickB.getMinY() - Data.VERTICAL_VELOCITY & ball.getLayoutY() < brickB.getMinY() + Data.VERTICAL_VELOCITY){
                    dy = -dy;
                }
            }

            //If the ball reaches the bottom or top border make the step negative
            if((ball.getLayoutY() >= (bounds.getMaxY() - ball.getRadius())) ||
                    (ball.getLayoutY() <= (bounds.getMinY() + ball.getRadius()))){
                dy = -dy;
            }
            //Moving the player's brick
            if(goRight & brickB.getMaxX() < bounds.getMaxX() + Data.PLAYER_BRICK_S & goRight & brickB.getMaxX() < bounds.getMaxX() - Data.PLAYER_BRICK_S){
                playerBrick.setX(playerBrick.getX() + Data.PLAYER_BRICK_S);
            }
            if(goLeft & brickB.getMinX() > bounds.getMinX() + Data.PLAYER_BRICK_S & goLeft & brickB.getMinX() > bounds.getMinX() - Data.PLAYER_BRICK_S){
                playerBrick.setX(playerBrick.getX() - Data.PLAYER_BRICK_S);
            }

        }
    }));
    timeline.setCycleCount(Timeline.INDEFINITE);
    timeline.play();    
}

除非您显示代码,否则我却无济于事,但我认为您应该使用GamePane.requestFocus()brick.requestFocus()来使GamePane/brick收听键盘输入。

根据javadoc的节点,node.requestfocus()方法

要求此节点获得输入焦点,并且该节点的 顶级祖先成为集中的窗口。

最新更新