JavaFX: classe de contrôleur et fx: id dans FXML



Il me semble que de nombreux articles utiles ne sont pas justifiés, non seulement ne consacrez pas quelques mots à la question la plus brûlante lorsque vous commencez à travailler avec JavaFX, mais les consacrez également, ils ne la divulguent toujours pas complètement. Et la question se pose comme suit: comment communiquer vos nœuds par leur fx: id et votre code. Comment les utilisez-vous dans différentes parties de votre code pour référencer votre API? C'est ce à quoi je vais essayer de répondre sous la coupe



Qu'est-ce que fx: id et avec quoi il est mangé



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


Quelque part ci-dessus, j'ai dit qu'il y avait de la magie dans javaFX. Il commence dans la classe View. Il semble que ce serait évident s'il était possible d'hériter des classes du contrôleur pour travailler avec id, mais le contraire se produit ... Pourquoi cela est fait, je ne suis pas entré dans les détails, même si je suis curieux de savoir pourquoi. Si des personnes bien informées ouvrent le voile du secret dans les commentaires, je serai très reconnaissant.




All Articles