当前位置: 首页 > 知识库问答 >
问题:

将StringProperty绑定到单例标签

齐建安
2023-03-14

我有一个名为menutext的单例。它负责在菜单中显示正确的文本。它会动态更新。

public class MenuText implements LanguageObserver {

    private MenuText() { //I want this to be private, only one instance should exist
        Config.getInstance().subscribe(this);
    }

    private static class MenuTextHolder {
        private static final MenuText INSTANCE = new MenuText();
    }

    public static MenuText getInstance() {
        return MenuTextHolder.INSTANCE;
    }

    @Override
    public void update(Language language) {
        System.out.println("Updating...");
        switch (language) {
            case ENGLISH -> {
                setText("Play");
            }
            case GERMAN -> {
                setText("Spielen");
            }
        }
    }

    private final StringProperty text = new SimpleStringProperty("Play");

    public StringProperty textProperty() {
        return text;
    }

    public String getText() {
        return text.get();
    }

    private void setText(String text) {
        this.text.set(text);
    }
}

我有一个fxml文件,但是MenuText不能有对它的引用。(这将与MVVM体系结构风格相矛盾)

<?import tiles.text.MenuText?>
<VBox alignment="TOP_CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity"
      prefHeight="1080.0" prefWidth="1920.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1"
      fx:controller="tiles.viewModel.GameMenuViewModel">

<!--here I want to bind to the text property-->
<Button text="???"/>

</VBox>
//Creation of items with application lifetime
public class ApplicationFactory {

    private Config config;

    public void build() {
        config = new Config();
    }

    public Config getConfig() {
        return config;
    }
}

这是正确的做法吗?我现在有了一个MenuFactory,它也是在JavaFXstart()方法中创建的。它设置场景的父级。

public class MenuFactory {
    public Parent getMenu(Config config, String fxmlLocation) {
        MenuText menuText = new MenuText(config);
        MenuViewModel menuViewModel = new MenuViewModel(config);

        try {
            FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(getClass().getResource(fxmlLocation)));
            loader.getNamespace().put("menuText", menuText);
            return loader.load();
        } catch (IOException e) {
            //...
        }
    }
}

start()mehtod如下所示:

    @Override
    public void start(Stage primaryStage) {
        ApplicationFactory applicationFactory = new ApplicationFactory();
        applicationFactory.build();

        MenuFactory menuFactory = new MenuFactory();

        Parent root = menuFactory.getMenu(applicationFactory.getConfig(), MENU);
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

这让它变得更加复杂,我不确定这是否正确。此外,我仍然不知道如何设置fxml文件中的菜单文本。我尝试过,但我认为这不是在FXML中设置命名空间的正确方法。

    <fx:define>
        <MenuText fx:id="menuText"/>
    </fx:define>

我阅读了这些文档,但不明白如何设置这个自定义命名空间。

共有1个答案

阎建华
2023-03-14

请注意,单例模式被广泛认为是一种反模式。但是,如果您真的想这样做:

最初,我使用 从fxml文件设置对menutext的引用

这才是正确的做法。您可以将其与fx:factory组合,以获取对没有(公共)默认构造函数的类实例的引用:

<fx:define>
    <MenuText fx:factory="getInstance" fx:id="menuText" />
</fx:define>
<Button text="${menuText.text}" />
MenuText menuText = ... ;
FXMLLoader loader = new FXMLLoader(getClass().getResource(...));
loader.getNamespace().put("menuText", menuText);
Parent root = loader.load();
<Button text="${menuText.text}" />

应该不使用额外的FXML代码。这种方法允许您避免使用单例模式(您基本上是将依赖项注入到FXML,这样您就可以轻松地将其与DI框架结合起来)。

 类似资料:
  • 本文向大家介绍Laravel 将单例绑定到服务容器,包括了Laravel 将单例绑定到服务容器的使用技巧和注意事项,需要的朋友参考一下 示例 我们可以将一个类绑定为Singleton: 这样,第一次将实例  'my-database'请求到服务容器时,将创建一个新实例。该类的所有后续请求都将返回第一个创建的实例:            

  • 我在JavaFX应用程序中使用MVP。 资源: 控制器: 看法 在我的InfoStageView中,只需初始化我的标签和样式我的视图。 如何将我的超链接绑定到我的标签。我尝试了一些方法,但没有成功。我的StringProperty不可点击,但很容易绑定。 我的目标:我想打开带有链接的浏览器。

  • 当我试图将一个列表元素绑定到JavaFX标签时,我遇到了一个问题。如果项目不在列表中,我没有问题。 垃圾收集器是这个问题的原因吗? Controller.class:(fxml文件的控制器) Context.java:(刷新变量的类) 要刷新标签,我使用

  • 我有一个关于多线程和StringProperty绑定的问题。 我有一个类CacheManager,它包含一个线程,可以根据服务器上的更改更新缓存。现在,我想用文本和进度百分比(JavaFX中的标签和进度条)通知用户。为此,我使用公共静态的DoubleProperty和StringProperty,它们是在CacheManager类中定义的。我只是这样装订: 现在,在Updater线程中,我更新了这

  • 问题内容: 我有一个关于多线程和StringProperty绑定的问题。 我有一个类,其中包含,该类使用服务器上的更改更新缓存。现在,我想用文本和进度百分比(在JavaFX 中为和)通知用户。我使用公共静态和对于这一点,这是在定义类。我只是这样绑定它: 现在,在Updater线程中,我更新了这些。使用此方法效果很好,并且可以完美地显示进度。但是,使用状态(这是的文本)更新会引发错误: 现在,我的问

  • 我有一个web表单,可以更新appliaction.properties,这样用户就不必转到文件并编辑它。我想从application.properties文件中加载值并显示在web表单TextField中。在用户编辑一些更改后,用户可以更新application.properties文件。 问题-如何将web表单绑定到application.properties文件,而不是在Spring中使用@