Reputation: 10253
I am looking for feedback on why we should use one method over the other as far as loading and displaying new FXML stages.
Most of the time, I see tutorials and such that show the loading of a stage done from a separate class. However, it can also be done within the FXML file's controller itself, and I personally see that way as being a bit cleaner and more manageable.
Consider the following Main.java class:
public class Main extends Application {
@Override
public void start(Stage stage) throws Exception {
// Method 1:
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Layout.fxml"));
loader.setController(new LayoutController());
stage.setScene(new Scene(loader.load()));
stage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
This seems to be the prevailing method. It creates the contoller and sets the Scene
and then shows it.
However, if we change the start()
method to this instead:
@Override
public void start(Stage stage) throws Exception {
LayoutController controller = new LayoutController();
controller.showStage();
}
and move the FXML loading code into the LayoutController
constuctor, the result is the same:
public class LayoutController {
@FXML
private Label label;
private Stage stage = new Stage();
public LayoutController() {
// Method 2:
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Layout.fxml"));
loader.setController(this);
stage.setScene(new Scene(loader.load()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void showStage() {
this.stage.showAndWait();
}
}
The benefit I see here is more separation between the view and logic. Everything about the LayoutController
and its associated FXML file are contained in one place.
So my question is this: what is wrong with the second approach? I am assuming it is not the standard method for a reason, but I'm not able to see any drawbacks.
Would a question like this be more suited to Code Review? I'm not really asking for opinions, as there seems to be a general "rule" that the first method be used.
Upvotes: 1
Views: 82
Reputation: 82461
In this case there is not much difference.
For larger programs the second approach is undesirable tough:
It violates the single responsibility principle:
The class is responsible for:
showAndWait
))Furthermore the way the class is designed in a way that prevents the responsibilities from being moved to other classes without issues.
In a larger program you likely want to create a class that manages passing data to views, arrange windows or display the view as part of a scene, ect. The second approach is ill suited for this.
Additionally it makes if harder to not repeat yourself. Unless you move the logic to a common supertype, you also need to implement the logic for showing the scene in every controller class. Repetition of the same or similar code results in code that is hard to maintain.
Note: Using a single class for loading the fxml and for use as controller is not necessarily a bad thing, but you should go with the Custom Component approach presented in Introduction to FXML.
Upvotes: 5