JavaFx如何避免创建一个巨大的控制器

问题描述 投票:1回答:3

我在JavaFX中有一个应用程序,它有一个带有菜单和工具栏的主场景,以及在按下一个菜单按钮后注入到这个主场景中的较小场景。

现在,HomeCntroller负责任一场景组件:Home Scene(带工具栏和菜单)和注入场景。如果注入的场景数量超过一个,这会导致我创建庞大,巨大且非常不专业的控制器。

如何拆分控制器责任?

现在我的控制器看起来像这样:更改仪表板窗格方法将较小的窗格注入我的主页面。

@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);
    }

}

为了更清楚,屏幕:

without injected second pane with injected second pane

有什么想法吗?

java design-patterns javafx
3个回答
3
投票

我建议你将主场景分成较小的场景,例如你可以有一个工具场景,一个标题场景,一个内容场景等等。然后你应该为每个场景都有一个控制器。

之后,我将使用发布者 - 订阅者模式来处理行为,例如当您按下设置场景上的按钮时,它会触发其他场景监听的事件,然后他们会相应地更改其状态。

我希望它很清楚,可以提供帮助!


1
投票

创建多个控制器,多个FXML文件 - 继续我之前提供给你的答案,JavaFX how to inject new FXML content to current Scene每个具有单独fxml文件的视图也有

fx:controller="appplication.ExampleViewController"

所以你要做的就是创建主控制器,就像上面提到的那样,它基本上是封装控件来改变你的动态容器的FRAME CONTAINER。如果你的应用程序非常丰富并且在一个控制器中有很多功能,你可以进一步打破你的观点:

例如取出菜单并将其放入分离的控制器中,并使用主控制器将其插入主视图中

/与方法setView()/中的方法相同

,你正在做的只是把它拿走以保持控制器代码更小,你不减少/增加场景图这种方式,没有一个缺点,它只是个人喜好。

最后你会得到更多的fxml文件和控制器。与上一个问题完全相同的是,你不需要额外的代码就可以实际重用已经提供的内容。

控制器之间的数据通过MODEL传递。 - 进一步了解MVC不要使用控制器中的应用程序数据只关心视图或将它们从模型传递到模型中


1
投票

为了避免庞大的控制器类,因为我使用多个选项卡,我将选项卡拆分为单个java文件。

我的解决方案是创建一个级联类:

  • 基数:包含FX类型的所有defs
  • Tab1扩展Base:Tab一个实现
  • Tab2扩展了Tab1:Tab两个实现
  • Controller扩展Tab2实现Initializable:Implements initialize(URL url,ResourceBundle resourceBundle)

要点:必须在当前选项卡中或之前定义任何访问的对象。 Base中的任何对象都可以在Controller中使用,而在Bass,Tab 1或Tab2中无法访问Controller的任何对象。

随意添加您的意见作为评论或提交改进。

© www.soinside.com 2019 - 2024. All rights reserved.