java - label.setText NullPointerException
javafx fxml (2)
Hola por primera vez aquí, pero aquí va:
Tengo una aplicación JavaFX que cambia dinámicamente las etiquetas de la interfaz de usuario FXML y los datos se extraen de una clase Player.
Las dos clases en cuestión son Player.java
e InterfaceHandler.java
.
La clase de jugador almacena los detalles del jugador y quiero pasar los detalles a la clase de interfaz que establece el texto en las etiquetas.
Como prueba, mi interfaz de usuario de FXML solo tiene un botón y dos etiquetas.
Si hace clic en el botón, llama al método handleButton
para establecer locationLabel
en "Town" fine.
Sin embargo, si llamo al método locationLabel()
en mi clase Player, obtengo una NullPointerException cuando se nameLabel.setText(name)
. A través de la depuración, encuentro que la cadena de nombre en la clase Interfaz es lo que debería ser "Dan".
¿Alguien puede ayudar?
Clase principal:
public class Main extends Application {
public void start(final Stage mainStage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("MainScreen.fxml"));
Scene scene = new Scene(root);
mainStage.setTitle("Main Screen");
mainStage.setScene(scene);
mainStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Clase de jugador:
public class Player{
InterfaceHandler ui = new InterfaceHandler();
public void setNameLabel() {
String name = "Dan";
ui.setName(name);
}
Clase InterfaceHandler:
public class InterfaceHandler implements Initializable {
public Label nameLabel;
public Label locationLabel;
public void handleButton(ActionEvent event) throws IOException {
locationLabel.setText("Town");
}
public void setName(String name){
nameLabel.setText(name);
}
}
MainScreen.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<AnchorPane id="AnchorPane" prefHeight="629.0" prefWidth="600.0" snapToPixel="true" style="-fx-background-color: beige;" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="application.InterfaceHandler">
<children>
<Button fx:id="button1" layoutX="512.0" layoutY="381.0" minWidth="14.0" mnemonicParsing="false" onAction="#handleButton" prefHeight="30.0" prefWidth="51.0" text="Town" visible="true" />
<Label fx:id="nameLabel" layoutX="57.0" layoutY="8.0" prefWidth="216.0" text="blank" />
<Label fx:id="locationLabel" layoutX="68.0" layoutY="27.0" prefWidth="193.0" text="blank" />
</children>
</AnchorPane>
Es porque no inyectó correctamente sus Labels
desde el archivo FXML.
Anota tus Label
vars. con la anotación FXML
:
public class InterfaceHandler implements Initializable {
@FXML
public Label nameLabel;
@FXML
public Label locationLabel;
public void handleButton(ActionEvent event) throws IOException {
locationLabel.setText("Town");
}
public void setName(String name){
nameLabel.setText(name);
}
}
Además, InterfaceHandler es un controlador al que usted hace referencia con el fx:controller
en su FXML. Esto instruye a FXMLLoader para crear una nueva instancia de InterfaceHandler cuando el cargador carga su FXML. Por lo tanto, no cree un nuevo InterfaceHandler en su clase Player, sino que haga de InterfaceHandler un parámetro constructor para Player y use loader.getController para sacar la instancia del controlador InterfaceHandler del FXMLLoader.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("MainScreen.fxml"));
Parent root = (Parent)loader.load();
Player player = new Player(loader.getController());
Scene scene = new Scene(root);
. . .
public class Player {
private InterfaceHandler ui;
public Player(InterfaceHandler ui) {
this.ui = ui;
}
public void setNameLabel() {
String name = "Dan";
ui.setName(name);
}
}
Simplemente agregue algo en la etiqueta, espacio o cualquier cosa pero no nulo.
<Label . . . " text="ANYTHING" . . . />