Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 761
G.Spansky Avatar asked Aug 30 '25 18:08

G.Spansky


1 Answers

I would recommend you to divide your main scene in smaller ones, for example you can have a tools scene, a header scene, a content scene and so on. Then you should have one controller for every scene.

After that I would use a publisher-subscriber pattern to deal with behaviors, like when you press a button on settings scene, it triggers an event that other scenes listen to and then they handle it changing their state accordingly.

I hope it was clear and can help!

like image 160
Johan Duke Avatar answered Sep 02 '25 06:09

Johan Duke