Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I automatically generate controller classes from FXML?

As I understand it, when using FXML to describe a Java FX scene, the controller class is written manually and it's member variables and methods can then be referenced from the .fxml file. When loading the scene using the FXMLLoader, member variables are set to the corresponding scene elements and methods are wired up to the corresponding events automatically. This works but is very cumbersome as changes need to be done in two places and any mistakes will only show up at runtime.

I've seen other GUI frameworks that allow you to instead generate the controller from a scene description as an abstract class which needs to be implemented to access the scene elements and handle the events. An example of what I mean:

I would create the following .fxml file (e.g. using the JavaFX Scene Builder):

<AnchorPane ... >
  <children>
     <Button fx:id="button" ... text="Button" onAction="#buttonPressed" />
  </children>
</AnchorPane>

Somewhere in my build process, the following .java file would be created (e.g. using a Maven plugin):

abstract class TestController {
    protected final Parent root;
    protected final Button button;

    {
        // Load test.fxml file
        // Assign scene elements to root and button
        // Attach event handler to the button that calls buttonClicked()
    }

    protected abstract void buttonClicked(ActionEvent event);
}

I could then, possibly multiple times, create a concrete implementation of that controller:

final class TestControllerImpl extends TestController {
    TestControllerImpl(String buttonLabel) {
        button.setText(buttonLabel);
    }

    @Override
    protected void buttonClicked(ActionEvent event) {
        button.setText("I've been clicked! What a great day!");
    }
}

Is there a project with the goal to do this? Or is there a problem with this approach applied to FXML?

I see the following benefits from this approach:

  • Declarations for member variables and methods for the controller are automatically generated.
  • All member variables are final and protected instead of non-final and either public or annotated.
  • The same for methods, they are protected instead of either public or annotated.
  • Not implementing a method or misspelling it's name will lead to a compiler error.
  • Programmatic setup of the scene can be done in the constructor instead of an initialize() method because the constructor will run after the scene has been loaded and its elements assigned to the member variables.
like image 379
Feuermurmel Avatar asked Feb 05 '14 10:02

Feuermurmel


People also ask

Can a FXML have multiple controllers?

During the loading of your FXML markup, there is only the provision to have one controller specified for your scene graph. You are able to load other FXML markup files and nest controllers, but I don't think that's what you're asking.

How do controllers work in JavaFX using FXML?

Specifying Controller Class in FXML Notice the fx:controller attribute in the root element (the VBox element). This attribute contains the name of the controller class. An instance of this class is created when the FXML file is loaded. For this to work, the controller class must have a no-argument constructor.

How do I create a controller class in Intellij?

1) Create a new Java class in the same place as your HelloWorldApplication. java class called HelloWorldController. java . 2) The first thing we need to do is tell Spring that this is a REST Controller, so you need to add a class level annotation of @RestController .

Is FXML annotation required?

You don't actually need any @FXML annotations if your fields are public . Of course, you should never make these fields public anyway; you should make them private , in which case all the @FXML annotations are required. But with the code as it is, omitting the annotations will make no difference.


1 Answers

This is now supported in SceneBuilder, NetBeans and in Eclipse. Note this works out of the box in NetBeans and SceneBuilder, but in Eclipse you first need the e(fx)clipse plugin.

SceneBuilder: With an FXML file open in the editor, enter the menu to select "View" and "Show Sample Controller Skeleton".

Eclipse: Open the fxml file so the contents are displayed in the code editing pane (you should see the fxml as plaintext xml with syntax highlighting inside Eclipse, not rendered visually in SceneBuilder). Right-click on the code in Eclipse and select "Code" and then "Generate Controller".

NetBeans: In NetBeans it is even easier, right-click the fxml file in the project explorer and select "Make Controller".

like image 183
Mishax Avatar answered Oct 19 '22 18:10

Mishax