如何使用相同的模型对象初始化 JavaFX 控制器?

2023-12-28

Scenario

我正在创建一个 GUI,其中多个视图引用同一模型对象。

我习惯什么

在 Swing 中,如果我希望所有视图都引用同一模型,我会将模型传递到构造函数中。

我目前在做什么

在 JavaFX 中,在加载每个视图/控制器后,我通过在视图/控制器(菜单栏、分割窗格、选项卡等)中使用 setter 方法来传递模型。我觉得这非常俗气和麻烦。此外,我发现它不起作用,因为在某些情况下,我需要在初始化某些控制器小部件之前模型已经存在于控制器中。

黯淡的替代品

(注意:我引用了这些 stackoverflow 问题:

  • Javafx 2.0 操作指南 Controller.java 文件中的 Application.getParameters() https://stackoverflow.com/questions/10134856/javafx-2-0-how-to-application-getparameters-in-a-controller-java-file/10136403#10136403
  • 传递参数 JavaFX FXML https://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml/14190310
  • 带有控制器的多个 FXML,共享对象 https://stackoverflow.com/questions/12166786/multiple-fxml-with-controllers-share-object/
  • 加载 FXML 时将参数传递给控制器 https://stackoverflow.com/questions/14370183/passing-parameters-to-a-controller-when-loading-an-fxml/14432578#14432578)

  • 依赖注入

    • 我看过这个网站,http://www.zenjava.com/2011/10/23/javafx-2-0-fxml-and-spring/ http://www.zenjava.com/2011/10/23/javafx-2-0-fxml-and-spring/,并且我对 google Guice 进行了一些研究,但我没有看到一种简单地为每个 JavaFX 视图/控制器提供相同模型对象的方法。看起来注入会为每个视图/控制器注入不同的模型。
  • 将模型对象保存为公共静态变量

    • 这是一个选择,但目前我不喜欢拥有如此开放和可用的公共静态模型的想法。显然,我可以将其设为私有静态变量,并具有 getter 和 setter,但我也不太喜欢这个想法。
  • 将参数从调用者传递到控制器

    • 我希望每个控制器在其构造函数中加载自身,并且希望每个自定义控制器自动注入到其父控制器中。例如,卡片概述选项卡会像这样加载自身:

      public CardOverviewTab() {
          FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("card_overview_tab.fxml"));
          fxmlLoader.setRoot(content);
          fxmlLoader.setController(this);
      
          try {
              fxmlLoader.load();
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
      
    • SingleGameSetup 控制器将卡概览选项卡自动注入到变量中:

      public class SingleGameSetupController extends AnchorPane {
      
          @FXML private CardOverviewTab cardOverviewTab;
      
          // Rest of the class
      }
      
    • fxml 中包含卡片概述选项卡的部分如下所示:

      <CardOverviewTab fx:id="cardOverviewTab" />
      
    • 这样我就不需要担心手动加载控制器,但我仍然有设置模型的问题。

  • 在 FXMLLoader 上设置控制器

    • 这个选项与我习惯的类似,将模型作为参数传递到构造函数中,但它仍然存在使用 FXMLLoader 手动加载控制器的问题。
  • 活动总线

    • 我没有对此进行过多的阅读,但从我所读到的内容来看,事件总线似乎不活跃且过时。
  • 辛格尔顿

    • 这类似于对控制器可以检索的模型对象的公共静态引用,但我再次寻找更好的解决方案。另外,我不想要单例模型。

我在寻找什么

有没有一种方法可以以不那么麻烦的方式传递模型对象?我正在寻找一种与将模型传递给构造函数一样简单的方法,但我不想通过 FXMLLoader 手动加载控制器,或者在加载控制器后设置模型。也许有一个类来检索模型是最好的选择,但我问只是为了以防万一有更好的方法。


Update

除了 afterburner.fx 之外,还可以结账胶子点燃 http://gluonhq.com/labs/ignite/:

Gluon Ignite 允许开发人员在其 JavaFX 应用程序中(包括在 FXML 控制器内)使用流行的依赖项注入框架。 Gluon Ignite 在几个流行的依赖注入框架(目前是 Guice、Spring 和 Dagger,但我们计划随着需求变得明显而添加更多)上创建了一个通用抽象。凭借 JSR-330 Gluon Ignite 的全面支持,在 JavaFX 应用程序中使用依赖项注入变得轻而易举。

将模型对象注入控制器也是通过@Inject,类似于afterburner.fx。

建议的方法

当您似乎正在寻找依赖注入框架时,我认为您最好的选择是使用afterburner.fx 框架 http://afterburner.adam-bien.com.

afterburner.fx 提供了一种使用标准 Java 将模型对象注入 JavaFX 控制器的方法@Inject http://docs.oracle.com/javaee/6/api/javax/inject/Inject.html注解。

替代依赖注入系统

Spring 庞大且复杂,除非您的应用程序需要它的许多其他功能,否则不应考虑它的复杂性。

Guice 比 Spring 简单得多,如果您需要一个具有众多功能(例如提供程序类)的依赖注入框架,Guice 是一个合理的选择。但从表面上看,您不需要 Guice 提供的所有功能,因为您只是想要一种在应用程序中传递对象的单例实例而不显式查找它们的方法。

因此,尝试一下 afterburner.fx 并看看它是否符合您的需求。

afterburner.fx 示例代码

这是注入模型实例的示例(NotesStore)使用 afterburner.fx 进入控制器。示例是直接从afterburner.fx 文档 http://afterburner.adam-bien.com.

import com.airhacks.afterburner.views.FXMLView;

public class NoteListView extends FXMLView {
    //usually nothing to do, FXML and CSS are automatically
    //loaded and instantiated
}

public class AirpadPresenter implements Initializable {    
    @Inject // injected by afterburner, zero configuration required
    NotesStore store;

    @FXML // injected by FXML
    AnchorPane noteList;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        //view constructed from FXML
        NoteListView noteListView = new NoteListView();

        //fetching and integrating the view from FXML
        Parent view = noteListView.getView();
        this.noteList.getChildren().add(view);
    }
}

跟随我.fx https://github.com/AdamBien/followme.fx是一个基本示例应用程序,演示如何使用 afterburner.fx。由于 Maven 依赖项不兼容,我在直接运行 followme.fx 时确实遇到了一些问题,所以我分叉它的代码 https://github.com/jewelsea/followme.fx并修复了一些阻止我开箱即用的问题。

回答评论中的补充问题

因此,从 NoteStore 示例来看,您是说我所要做的就是添加 afterburner 框架依赖项并将 @Inject 放在我的模型变量上?

不,您还需要创建一个扩展 FXMLView 的关联类,并通过新调用实例化该类(类似于上面示例代码中创建 NotesListView 的方式)。如果您有兴趣继续研究 afterburner.fx 框架,请使用 followme.fx 项目作为基础,因为它为使用该框架的非常简单的可执行示例提供了完整的源代码。

我尝试了 google guice 并让它工作。 。 。您将在构造函数中看到手动注入游戏设置对象。

我认为您不必像那样手动使用 Guice 注入器。我想你可以设置控制器工厂 http://docs.oracle.com/javafx/2/api/javafx/fxml/FXMLLoader.html#setControllerFactory%28javafx.util.Callback%29在 FXMLLoader 实例上启动注入。这就是如何FXMLView https://github.com/AdamBien/afterburner.fx/blob/master/src/main/java/com/airhacks/afterburner/views/FXMLView.java在 afterburner.fx 中可以做到这一点。 Guice 中使用的注入机制的具体细节将与 afterburner.fx 机制有所不同,但我认为设置控制器工厂的广泛概念仍然相似。

答案中有一个使用 FXML 和 Guice 的集合控制器工厂的演示:在 Guice 的模块配置中关联 FXML 和控制器 https://stackoverflow.com/questions/15990777/associating-fxml-and-controller-in-guices-module-configuration.

遗憾的是,没有一种更直接的方法可以做到这一点,并且不会给您带来这么多困难。

作为一个无关紧要的个人旁注,我对一般的依赖注入框架主题有点矛盾。当然,它们可以提供帮助,但很多时候,对于简单的事情,我通常可以使用带有 getInstance 方法的单例,而不是更复杂的框架。不过,我确实看到它们在较大的项目中如何有用,而且它们在某些 Java 框架中当然非常流行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用相同的模型对象初始化 JavaFX 控制器? 的相关文章

随机推荐

  • MVC 3 不绑定可为 null 的 long

    我创建了一个测试网站来调试我遇到的问题 看来要么是我传入的 JSON 数据错误 要么是 MVC 无法绑定可为 null 的 long 当然 我使用的是最新的 MVC 3 版本 public class GetDataModel public
  • UISearchController iOS 11 定制

    在 iOS 11 之前我一直使用以下代码来自定义外观UISearchController搜索栏 var searchController UISearchController searchResultsController nil sear
  • 使用 HTML5 语义标记搜索结果列表

    如果您只需要一些有用的东西 那么制作搜索结果列表 例如在 Google 中 并不难 然而现在 我想利用 HTML5 语义的优势来完美地做到这一点 目标是定义标记搜索结果列表的事实上的方式 该列表可能被任何未来的搜索引擎使用 对于每一次点击
  • Azure 权限中的“变体”是什么

    在关于这个的例子中https learn microsoft com en us powershell microsoftgraph find mg graph command view graph powershell 1 0 https
  • java到底有没有指针? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 限制 HTML5 文本区域中的行数

    我正在寻找问题的解决方案 但找不到 它可以是 AngularJS 或 Javascript 然后我将其翻译成 AngularJS 问题是我必须限制简单文本区域的行数 HTML5 的属性 rows x 仅限制视图 我必须限制线路 问题是 即使
  • urllib2 基本身份验证的奇怪之处

    我正用这个把头撞在墙上 我一直在尝试每个示例 阅读我可以在网上找到的有关 urllib2 基本 http 授权的所有最后一点 但我无法弄清楚是什么导致了我的特定错误 更令人沮丧的是 该代码适用于一个页面 但不适用于另一页面 登录 www m
  • Python 2.7 尝试并排除 ValueError

    我使用 int raw input 查询预计为 int 的用户输入 然而 当用户没有输入整数 即只是按回车键时 我会得到一个 ValueError def inputValue inputMatrix rangeRows rangeCols
  • 尝试在 woocommerce Analytics -> 订单报告表中添加订单项目名称列(并输出到 csv 文件)

    我正在尝试向 WooCommerce Analytics gt 订单提供的表中添加一列 并且该订单的商品名称 不是产品名称 显示在其上 我添加了一个钩子并尝试提取订单中商品的所有名称 这个钩子是我之前使用过的 它在 WooCommerce
  • 结构与类中使用的泛型

    假设我们有以下内容struct使用泛型的定义 public struct Foo
  • SlingModels:从资源改编时可以注入 SlingHttpServletRequest 吗?

    我是 SlingModels 的新手 注释还不是很清楚 我目前正在尝试将一些基本基础组件从 AEM 6 2 转换为使用 SlingModels 对于图像组件 基础 JSP 使用 SlingHttpServletRequest 来设置 Ima
  • 装饰器 @page、@component 和 @app 在 ionic 2 应用程序中意味着什么?

    我见过 app and page and 成分似乎可以互换使用 我不知道有什么区别 ionic2 文档在这方面非常糟糕 那么 ionic 2 应用程序的这些装饰器之间的根本区别是什么 什么时候你会使用其中一个而不是另一个 Page 和 Ap
  • jQuery:只有直接后代选择器

    我有以下结构 ul li a link a ul li a link a ul li a link a li li a link a li li a link a li ul li li a link a ul ul li ul li ul
  • 带参数的单例

    我需要用一些参数实例化一个单例类 我现在的做法是 class SingletonExample private SingletonExample mInstance other members private SingletonExampl
  • Sequel Pro 在 Docker 中使用 Mysql

    我用 docker compose 构建了 2 个 docker 容器 我在 Mac 上使用 Docker 没有 boot2docker version 2 services drupal web image drupal latest p
  • Outlook Web 应用程序的任务窗格插件

    通过命令加载项 任务窗格将出现在 Outlook 桌面应用程序的右侧 同样 是否可以让任务窗格显示在 Outlook Web 应用程序的右侧 提前致谢 跟进这个 插件命令 https blogs msdn microsoft com exc
  • 将数组颠倒过来?

    我不是在谈论array flip 我想反转一个没有数字 字母基础的数组 只是倒挂 Example array music television hollywood Will be array hollywood television mus
  • 为 Azure 警报配置电子邮件模板

    有没有办法 我可以为 Azure 警报配置电子邮件模板 我已为指标创建了电子邮件警报 并且需要在指标值超过阈值时发送自定义电子邮件 无法自定义 Azure 警报的电子邮件模板 作为解决方法 你可以在 Azure 警报上配置 Webhook
  • Android如何以编程方式获取使用whats app应用程序的联系人列表

    我在此应用程序中使用小型 Android 应用程序 我尝试获取使用 Whats App 应用程序的联系人 并在联系人更新他 她的个人资料图片和状态时 从我的应用程序中提醒我选择的 Whats App 联系人 您可以查询内容光标以查看联系人具
  • 如何使用相同的模型对象初始化 JavaFX 控制器?

    Scenario 我正在创建一个 GUI 其中多个视图引用同一模型对象 我习惯什么 在 Swing 中 如果我希望所有视图都引用同一模型 我会将模型传递到构造函数中 我目前在做什么 在 JavaFX 中 在加载每个视图 控制器后 我通过在视