2017-10-10 1 views
0

Zu Schulungszwecken versuche ich, Hotkeys zu meiner Javafx-Anwendung hinzuzufügen. Mit meinem Beispielcode kann ich nicht über Hotkey auf mein Label zugreifen. Mit einem Knopf kann ich die gleiche Methode aufrufen, um mein Etikett erfolgreich zu aktualisieren.JavaFX NPE beim Aktualisieren des Labels über den Hotkey

The View:

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

<?import java.lang.*?> 
<?import java.util.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 

<AnchorPane id="AnchorPane" prefHeight="62.0" prefWidth="91.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fx.probleme.SampleViewController"> 
    <children> 
     <Label id="label" fx:id="label" layoutX="14.0" layoutY="45.0" text="Label" /> 
     <Button layoutX="20.0" layoutY="14.0" mnemonicParsing="false" onAction="#updateText" text="Button" /> 
    </children> 
</AnchorPane> 

Und der Controller:

package fx.probleme; 

import javafx.application.Application; 
import javafx.fxml.FXML; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.input.KeyCode; 
import javafx.scene.input.KeyEvent; 
import javafx.stage.Stage; 

public class SampleViewController extends Application { 

    @FXML 
    Label label; 

    @FXML 
    void updateText() { 
     label.setText(label.getText() + "+"); 
    } 

    @Override 
    public void start(Stage stage) throws Exception { 
     Parent parent = FXMLLoader.load(this.getClass().getResource("SampleView.fxml")); 
     Scene scene = new Scene(parent); 
     scene.setOnKeyPressed((final KeyEvent keyEvent) -> { 
      if (keyEvent.getCode() == KeyCode.NUMPAD0) { 
       updateText(); 
      } 
     }); 
     stage.setScene(scene); 
     stage.show(); 
    } 

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

Antwort

0

Sie erhalten NullPointerException, weil zu diesem Zeitpunkt die Label nicht initialisiert wird, wird die Initialisierung in der initialize getan. Zuerst haben Sie Ihre Hauptklasse mit Ihrer Controller-Klasse gemischt, möchten Sie vielleicht trennen, setzen Sie einen Controller, der implements Initializable, danach in der initialize Methode können Sie jede Methode der Komponenten aufrufen, weil darin alle Komponenten kommentiert von @FXML werden initialisiert. In Ihrem Fall ist in Start-Methode noch nicht initialisiert. Außerdem möchten Sie möglicherweise nicht die Methode der Szene verwenden, anstatt Ereignisse, Aktionen zu Ihrem Inhaltsfenster hinzuzufügen, in Ihrem Fall zu AnchorPane.

Ich würde vorschlagen, die Controller-Klasse von Ihrer Hauptklasse zu trennen und implementieren Initializable. Dies hilft Ihnen, eine bessere Sicht auf Ihre Anwendung zu haben. Sie können sehen, wo genau Ihre Komponenten initialisiert wurden, ob Sie sicher sind, ihre Methoden zu verwenden, ohne NPE.

Wenn Sie es nicht in einer separaten Klasse tun möchte (was empfohlen wird) Sie fx:id für AnchorPane in der .fxml Datei hinzufügen können, dann können Sie die Methode zu onKeyPressed hinzufügen, wie Sie für das Button tat.

+0

Danke für Ihre Antwort. Ich lehre javafx selbst und habe gerade gelernt, dass meine 'Application'-Klasse nicht die 'Controller'-Klasse sein sollte. Ihr Tipp auf ein 'onKeyPressed' Event auf ex. Der Inhaltsbereich ist ebenfalls gültig, trotzdem werde ich 'Controller' und' Application' trennen, um den richtigen Weg zu finden. Andere Leser: Ich fand diese ausgezeichnete Erklärung, warum sie zu trennen: https://stackoverflow.com/questions/33303167/javafx-can-application-class-be-the-controller-class –

Verwandte Themen