I cant get my java fx project to respond to keyboard event handlers

I cant get my javafx project to respond to keyboard events. I want to move the rectangle right and left in response to arrow keys. I registered the controller class in fxml and registered the handling event with the rectangle. Here are my three classes:

here is the main

package application;

import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.stage.Stage;


public class Main extends Application  {
    @Override
    public void start(Stage primaryStage) {
        try {
               String fxmlResource = "/application/SpaceUniverse4.1.fxml";
               Parent panel;
               panel = FXMLLoader.load(getClass().getResource(fxmlResource));

               //MissionControl controller = new MissionControl();

               Scene scene = new Scene(panel);

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

            //panel.requestFocus();
            } catch(Exception e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        launch(args);
    }
}

here is the controller:

package application;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;


public class MissionControl
{

    @FXML
    private AnchorPane universe;

    @FXML
    private Rectangle bullet1;

    @FXML
    private Rectangle bullet2;

    @FXML
    private Rectangle ship;

    @FXML
    private Circle alien00;

    @FXML
    private Circle alien01;

    @FXML
    private Circle alien02;

    @FXML
    private Circle alien03;

    @FXML
    private Circle alien04;

    @FXML
    private Circle alien05;

    @FXML
    private Circle alien10;

    @FXML
    private Circle alien11;


    @FXML
    private Circle alien12;

    @FXML
    private Circle alien13;

    @FXML
    private Circle alien14;

    @FXML
    private Circle alien15;

    @FXML
    private Circle alien20;
    @FXML

    private Circle alien21;

    @FXML
    private Circle alien22;

    @FXML
    private Circle alien23;

    @FXML
    private Circle alien24;//has bullet emanating


    public MissionControl() {}

    @FXML
    void initialize() {}

    @FXML
     void handleKeyboardInput(KeyEvent event) 
    {
            if (event.getCode() == KeyCode.LEFT)
            {
               while(ship.getX()>=14) 
               ship.setTranslateX(-5);
            }

            else if (event.getCode() == KeyCode.RIGHT)
            {
                while(ship.getX()<=500) 
               ship.setTranslateX(+5);
            }
    }

    @FXML
    void MouseControl(ActionEvent e)
    {   
    }
}

here is the fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.*?>
<?import javafx.scene.shape.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>

<VBox prefHeight="500.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MissionControl">
  <children>
    <AnchorPane fx:id="universe" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="500.0" prefWidth="500.0" VBox.vgrow="ALWAYS">

        <Circle fx:id="alien00" fill="DODGERBLUE" layoutX="22.0" layoutY="22.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien01" fill="DODGERBLUE" layoutX="62.0" layoutY="22.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien02" fill="DODGERBLUE" layoutX="102.0" layoutY="22.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien04" fill="DODGERBLUE" layoutX="182.0" layoutY="22.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien10" fill="DODGERBLUE" layoutX="22.0" layoutY="62.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien11" fill="DODGERBLUE" layoutX="62.0" layoutY="62.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien12" fill="DODGERBLUE" layoutX="102.0" layoutY="62.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien13" fill="DODGERBLUE" layoutX="142.0" layoutY="62.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien03" fill="DODGERBLUE" layoutX="142.0" layoutY="22.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien14" fill="DODGERBLUE" layoutX="182.0" layoutY="62.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien20" fill="DODGERBLUE" layoutX="22.0" layoutY="102.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien21" fill="DODGERBLUE" layoutX="62.0" layoutY="102.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien22" fill="DODGERBLUE" layoutX="102.0" layoutY="102.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien23" fill="DODGERBLUE" layoutX="142.0" layoutY="102.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien05" fill="DODGERBLUE" layoutX="222.0" layoutY="22.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien15" fill="DODGERBLUE" layoutX="222.0" layoutY="62.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Circle fx:id="alien24" fill="DODGERBLUE" layoutX="182.0" layoutY="102.0" radius="14.0" stroke="BLACK" strokeType="INSIDE" />
        <Box layoutX="230.0" layoutY="299.0" />
        <Rectangle fx:id="ship" arcHeight="5.0" arcWidth="5.0" fill="#e10707" height="47.0" layoutX="236.0" layoutY="476.0" onKeyPressed="#handleKeyboardInput" stroke="BLACK" strokeType="INSIDE" width="28.0" />
        <Rectangle fx:id="bullet2" arcHeight="5.0" arcWidth="5.0" fill="#000e1b" height="18.0" layoutX="178.0" layoutY="116.0" stroke="BLACK" strokeType="INSIDE" width="9.0" />
        <Rectangle fx:id="bullet1" arcHeight="5.0" arcWidth="5.0" fill="#010e1b" height="18.0" layoutX="246.0" layoutY="413.0" stroke="BLACK" strokeType="INSIDE" width="9.0" />
  </children>
     <cursor>
        <Cursor fx:constant="S_RESIZE" />
     </cursor>
</AnchorPane>

1 answer

  • answered 2018-11-08 14:40 Matt

    Change you handle method to this the reason you couldn't move it more than once was that you were using .getX() which was returning 0 this worked for me good luck

    @FXML
    void handleKeyboardInput(KeyEvent event) {
        int currentX = (int) ship.getLayoutX();
        if (event.getCode() == KeyCode.LEFT && ship.getLayoutX() >= 14) {
            currentX = currentX - 5;
            ship.setLayoutX(currentX);
        } else if (event.getCode() == KeyCode.RIGHT && ship.getLayoutX() <= 500) {
            currentX = currentX + 5;
            ship.setLayoutX(currentX);
        }
    }
    

    Use this if you want to accept input on the whole screen for key presses

    universe.getParent().getScene().setOnKeyPressed(this::handleKeyboardInput);