Java Tutorial #63

JavaFX Nodes bewegen

2023-12-23 | credits: mimadeo/ stock.adobe

Thema in Kurzform

Gerade in spielorientierter Software ist es notwendig, dass sich einzelnde Nodes durch Nutzersteuerung von einem Ort zum anderen bewegen lassen. In diesem Tutorial zeigen wir dir drei Wege, genau das hinzukriegen: Über Buttonklick, via Tastatur-Input und über einen Klick mit der Maus. 

Bewegung über Buttons

Für unser Beispiel erstellen wir ein kleines Rechteck, das sich mithilfe von vier Buttons jeweils 20 Pixel nach oben, links, rechts und unten bewegen soll: 

JavaFX Nodes via Buttons bewegen

Buttons und Rechteck erstellen

Für die Gestaltung der vier Richtungs-Buttons sowie dem Rechteck-Node verwenden wir dieses JavaFX-Programm: 

// Buttons erstellen
Button b1 = new Button("HOCH");
b1.setPrefSize(100, 25);
b1.setLayoutX(100);
b1.setLayoutY(50);

Button b2 = new Button("LINKS");
b2.setPrefSize(100, 25);
b2.setLayoutX(50);
b2.setLayoutY(75);

Button b3 = new Button("RECHTS");
b3.setPrefSize(100, 25);
b3.setLayoutX(150);
b3.setLayoutY(75);

Button b4 = new Button("RUNTER");
b4.setPrefSize(100, 25);
b4.setLayoutX(100);
b4.setLayoutY(100);

// Rechteck-Node erstellen
Rectangle rechteck = new Rectangle(125,200,50,50);
rechteck.setFill(Color.FUCHSIA);
rechteck.setStroke(Color.BLACK);
rechteck.setFocusTraversable(true);

// Scene erstellen
AnchorPane ap = new AnchorPane();
ap.getChildren().addAll(b1, b2, b3, b4, rechteck);
Scene s = new Scene(ap, 600, 400);

EventHandler auf Buttons setzen

Es ist jetzt sehr einfach, das Rechteck bewegen zu lassen. Wie wir im Kapitel zum EvenHandling gesehen haben, können wir über die Button-Methode setOnAction() und einem Lambda-Ausdruck einen EventHandler auf jeden der vier Buttons legen. Bei einem Klick auf einen der Buttons, wir jeweils eine Aktion ausgeführt. 

In unserem Fall soll das Rechteck um je 20 Pixel in eine der vier Richtungen bewegt werden. Je nachdem, welcher Button geklickt wird. Die Position des Rechtecks wird dabei über die Methoden setY() und setX() neu bestimmt:

b1.setOnAction(e -> {
    rechteck.setY(rechteck.getY() - 20);
});
b2.setOnAction(e -> {
    rechteck.setX(rechteck.getX() - 20);
});
b3.setOnAction(e -> {
    rechteck.setX(rechteck.getX() + 20);
});
b4.setOnAction(e -> {
    rechteck.setY(rechteck.getY() + 20);
});

Das war's auch schon ☺️

Bewegung über Tastatur-Pfeiltasten

Von der Code-Masse noch einfacher ist es, unser Rechteck-Node via Tastatureingaben zu bewegen (z.B. WASD-Movement). 

Da wir die vier Buttons von oben nicht mehr benötigen, nehmen wir sie aus dem Programm. Stattdessen legen wir den EventHandler, der auf die Tastatur hört, direkt das Rechteck-Node. Und so sieht das Stück aus: 

// Rechteck-Node erstellen
Rectangle rechteck = new Rectangle(125,200,50,50);
rechteck.setFill(Color.FUCHSIA);
rechteck.setStroke(Color.BLACK);
rechteck.setFocusTraversable(true);

// EventHandler
rechteck.addEventHandler(KeyEvent.KEY_PRESSED, (key) -> {

if (key.getCode() == KeyCode.W) {
    rechteck.setY(rechteck.getY() - 20);
}
else if (key.getCode() == KeyCode.A) {
    rechteck.setX(rechteck.getX() - 20);
}
else if (key.getCode() == KeyCode.D) {
    rechteck.setX(rechteck.getX() + 20);
}
else if (key.getCode() == KeyCode.S) {
    rechteck.setY(rechteck.getY() + 20);
}

});

// Scene erstellen
AnchorPane ap = new AnchorPane();
ap.getChildren().add(rechteck);
Scene s = new Scene(ap, 600, 400);
primaryStage.show();
primaryStage.setScene(s);

Mit der Methode addEventHandler() setzen wir auf die Rectangle-Referenz rechteck den EventHandler, der auf Keyboard-Eingaben lauscht und reagiert, sofern eine der Tasten W, A, S oder D gedrückt wird. Das Rechteck wird dann entsprechend in eine der vier Richtungen um 20 Pixel versetzt. 

Fokus zurückholen

In der Regel funktioniert das Bewegen des Rechteck-Nodes über die Tastatur nur dann, wenn das Node auch den Fokus hat. Sollte der Fokus auf ein anderes Node (ungewollt) übergehen, können wir ihn einfach wieder auf das Rechteck zurückholen. Dazu verwenden wir folgende Methode: 

Platform.runLater(() -> rechteck.requestFocus());

Diesen Lambda-Ausdruck bauen wir am besten direkt vor dem Codeblock des EventHandlers ein. Wollen wir außerdem sicherstellen, das zu jeder Tastatureingabe der Fokus (erneut) auf das Rechteck-Node zurückgeholt wird, platzieren wir die Anweisung zusätzlich direkt zu Beginn innerhalb des EventHandlers ein. 

Bewegung über Mausklick

Kommen wir jetzt noch dazu, unser Rechteck-Node mithilfe eines Mausklicks zu steuern. Das heißt: Das Node soll an die Stelle "springen", wo wir mit der linken Maustaste geklickt haben:

// Rechteck-Node erstellen
Rectangle rechteck = new Rectangle(125,200,50,50);
rechteck.setFill(Color.FUCHSIA);
rechteck.setStroke(Color.BLACK);
rechteck.setFocusTraversable(true);

// Scene erstellen
AnchorPane ap = new AnchorPane();
ap.getChildren().add(rechteck);
Scene s = new Scene(ap, 600, 400);
primaryStage.show();
primaryStage.setScene(s);

// EventFilter erstellen 
s.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent mouseEvent) {
    rechteck.setX(mouseEvent.getX());
    rechteck.setY(mouseEvent.getY());
    }
});

Wie du siehst, legen wir einen EventFilter direkt auf die Scene-Referenz, weshalb wir uns um den Fokus nicht kümmern müssen. 

Das im EventFilter verbaute MouseEvent-Objekt zieht sich die Koordinaten des Maus-Klicks (getX() und getY()). Mit diesen Werten setzen wir dann die Position des Rechecks mit den setter-Methoden einfach neu. 

So einfach ist das 🤩

Werbung

Java lernen

Werde zum Java Profi!

PHP Lernen

Lerne serverbasierte Programmierung

JavaScript lernen

Skille dein Webcoding

FALCONBYTE.NET

Handmade with 🖤️

© 2018-2023 Stefan E. Heller

Impressum | Datenschutz | Changelog

Falconbyte Youtube Falconbyte GitHub facebook programmieren lernen twitter programmieren lernen discord programmieren lernen