JavaFX: Controller class and fx: id in FXML



It seems to me that many useful articles are not justified, not only do not devote a couple of words to the most burning question when starting to work with JavaFX, but also devote, they still do not fully disclose it. And the question arises as follows: how to communicate your nodes by their fx: id and your code. How do you use them in different parts of your code to reference your API? This is what I will try to answer under the cut



What is fx: id and what it is eaten with



- , 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

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.



  1. FXML .



  2. 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, , .


Somewhere above, I said that there is magic in javaFX. It starts in the View class. It seems, it would be obvious if it was possible to inherit classes from the controller to work with id, but the opposite happens ... Why this is done, I did not go into details, although I am curious why this is so. If in the comments knowledgeable people open the veil of secrecy, I will be very grateful.




All Articles