Me parece que muchos artículos útiles no están justificados, no solo no dedicas un par de palabras a la pregunta más candente cuando comienzas a trabajar con JavaFX, sino que también las dedicas, todavía no lo desvelan por completo. Y la pregunta surge de la siguiente manera: cómo comunicar sus nodos por su fx: id y su código. ¿Cómo los usa en diferentes partes de su código para hacer referencia a su API? Esto es lo que intentaré responder bajo el corte.
Que es fx: id y con que se come
- , StackOverFlow , , fx:id . . , , .
, , ( ), , StackOverFlow. , , fx:id, FXML . , . " node fx:id ".
, . NullPointerException. , , , id. , exception, , FXML - java-. , , .
, , , . MVC , JavaFX. , . , , javaFX FXML, java , . , , fx:id, .
, , , Oracle. , Oracle, fx:id. , , .
, , .
? , FXML , -, Application, start() ( Main, ) fx:id. . , , , .
, "hello world":
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.control.Button?>
<Pane xmlns="http://javafx.com/javafx/1.8.0.261" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Main">
<Button fx:id="fxButton" text="clickMe" onAction="#click"/>
</Pane>
public class Main extends Application {
@FXML
public Button fxButton;
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("YourFXML.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
public void click(ActionEvent actionEvent) {
System.out.println("Hello World");
fxButton.setText("Hey!");
}
}
. , FXML Pane, Button, fx:id="fxButton", , - onAction="#click". click .
, , . ? . , . . MVC - , , , , " ". , — …
, , , click , . start(), , fxButton (/ , , fx:id):
public class Main extends Application {
@FXML
public Button fxButton;
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("YourFXML.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
// , ( ):
fxButton.addEventHandler(MouseEvent.MOUSE_CLICKED, mouseEvent -> System.out.println("Hello World"));
}
}
IDE
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$154(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
at sample.Main.start(Main.java:25)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
… 1 more
Exception running application sample.Main
Process finished with exit code 1
, , , . , FXML , , click , fx:id.
, FXML. java FXML, , , Button fxButton, — . , . , , ...
IDE, , IDEA, , ( FXML Controller, Main ). . , , Main , , .
, node FXML , , . , . , fx:id.
, ( , fx:id ), ( — ), NullPointerException , , WHY? - , fx:id, , , , - ? ?
, , ...
, , . , . , , , . , . javaFX, .
FXML. .
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<Pane xmlns="http://javafx.com/javafx/1.8.261" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
<VBox layoutX="14.0" prefHeight="50.0" prefWidth="50.0">
<Button fx:id="fxButton" onAction="#click" text="clickMe" />
<Label fx:id="labelFx" minHeight="17.0" minWidth="185.0" text="label" />
</VBox>
</Pane>
Main. , , FXML
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("YourFXML.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Controller. FXML java .
public class Controller extends View implements Initializable {
@FXML
private Button fxButton;
@FXML
private Label labelFx;
@FXML
Label localLabel;
@FXML
public void click(ActionEvent actionEvent) {
System.out.println("Hello World");
fxButton.setText("Hey!");
labelLocalInitialize();
}
private void labelLocalInitialize(){
localLabel = labelFx;
localLabel.setText("local variable control");
}
@Override
public void initialize(URL location, ResourceBundle resources) {
// View labelFx
setViewLabelFxText("transfer of control in View \"labelFx\" variable");
// , ,
fxButton.addEventHandler(MouseEvent.MOUSE_CLICKED, mouseEvent -> System.out.println("Listener triggered"));
}
}
View. , .
public class View {
@FXML
private Label labelFx;
public void setViewLabelFxText(String text){
labelFx.setText(text);
}
}
View , fx:id.
FXML .
id node , node fx:id.
, . :
FXML labelFx, initialize() , , .
:
"Hello World", "Hey!", labelLocalInitialize(), labelFx. , labelFx .
:
- initialize(), node fx:id. node, FXML. Controller View fx:id
- onAction ( ) FXML, , , click, , initialize
- fx:id , View, , View.
- JavaFX FXML Controller, Main. , . , FXML. . , FXML , , .
- Main.java — , FXML. , .
- Controller.java — , java FXML . , . fx:id, , .
En algún lugar arriba, dije que hay magia en javaFX. Comienza en la clase Ver. Parece, sería obvio si fuera posible heredar clases del controlador para trabajar con id, pero ocurre lo contrario ... Por qué se hace esto, no entré en detalles, aunque tengo curiosidad por qué es así. Si personas conocedoras abren el velo del secreto en los comentarios, estaré muy agradecido.