G.Spansky G.Spansky - 2 months ago 10
Java Question

JavaFx how to avoid creating one huge controller

I have an app in JavaFX, which has main scene with menu and toolbar, and smaller scenes, which are injected into this main scene, after one of menu buttons are being pressed.

Now, HomeCntroller is responsible for either scene components: Home Scene (with toolbar and menu), and injected scene. This leads me to create massive, huge and very unprofessional controller if number of injected scenes is more than one.

How to split controller responsibility?

Now my Controller looks like this:
changeDashboardPane method injects smaller Pane into my main HomePane.

@Component
@RequiredArgsConstructor(onConstructor = @__(@Autowired) )
public class HomeController extends AbstractController {
private static final Logger LOG = Logger.getLogger(HomeController.class);

private final BudgetProfileService budgetProfileService;

@FXML
private Label usernameLabel;

@FXML
private ComboBox<String> budgetProfilesComboBox;

@FXML
private AnchorPane dashBoardPane;

@FXML
public void initialize() {
refreshUsernameLabel();
getAllBudgetProfiles();
changeDashboardPane(PaneFactoryKeys.FINANCES_PANE);
}

private void refreshUsernameLabel() {
String username = UserAccountProvider.getLoggedUser().getUsername();
usernameLabel.setText(username);
}

private void getAllBudgetProfiles() {
List<String> budgetProfileNames = budgetProfileService.getAllBudgetProfileNames();
if (!budgetProfileNames.isEmpty()) {
budgetProfilesComboBox.getItems().clear();
budgetProfilesComboBox.getItems().addAll(budgetProfileNames);
}
}

@FXML
public void handleFinancesButtonAction() {
changeDashboardPane(PaneFactoryKeys.FINANCES_PANE);
}

@FXML
public void handlePeriodButtonAction() {
changeDashboardPane(PaneFactoryKeys.PERIOD_PANE);
}

@FXML
public void handleStatisticsButtonAction() {
changeDashboardPane(PaneFactoryKeys.STATISTICS_PANE);
}

@FXML
public void handleSettingsButtonAction() {
changeDashboardPane(PaneFactoryKeys.SETTINGS_PANE);
}

private final void changeDashboardPane(String paneFactoryKey) {
double injectedPanePosition = 0.0;
Pane paneToChange = getPaneFromFactory(paneFactoryKey);
dashBoardPane.getChildren().clear();
AnchorPane.setTopAnchor(paneToChange, injectedPanePosition);
dashBoardPane.getChildren().add(paneToChange);
}

}


To get this more clear, screens:

without injected second pane
with injected second pane

Any ideas guys?

Answer

Create multiple controllers , multiple FXML files - to continue on my answer that i provided you before, JavaFX how to inject new FXML content to current Scene each of those views that have separate fxml file also has

fx:controller="appplication.ExampleViewController"

attached to it.So what you do is create main controller as was mentioned , that is basically the FRAME CONTAINER that encapsulates controls to change your dynamic container.If your application is really ui rich and have a lot of functionality in one controller , you can break down your view even further:

For instance take out menu and put it into separated controller , and insert it into your main view with main controller

/same way as in method setView()/

, what you are doing is just taking it away to keep controller code smaller, YOU DONT DECREASE/INCREASE SCENE GRAPH THIS WAY, doesnt have a drawback its just a personal preference.

You gonna end up with more fxml files and controllers in the end.Its all the same thing as from your previous question there is no additional code needed you can actually reuse what was already provided.

Data between controllers are passed thru MODEL. - look more into MVC dont work with application data in controllers only care about view or passing them from/into model