在 fxml 中结合国际化字符串和非国际化字符串

Combine internationalized string with noninternationalized in fxml

在我的 FXML 文件中有

<Label text="%label.total" />

我在属性文件中有

label.total=Total

但是,我想在屏幕上显示 Total:。不仅针对此标签,还针对 fxml 文件中的许多标签。我不想将 : 添加到属性文件中,因为这似乎是错误的,因为在这里我们必须只保留不同语言的字符串。

是否可以将 "%label.total"":" 结合起来?或者这种情况使用了其他解决方案?

这看起来应该比实际更容易。 FXML 加载器在其名称空间中自动拥有资源包,键为 resources。如果资源包是 java.util.Map,则

<Label text="${resources.labelText + ':'}$ />

会起作用(属性文件中的键更改为 labelText)。但是,FXMLLoader 对待资源包的方式与对待地图的方式不同,因此最终只是在资源包中寻找 getLabelText() 方法。允许以与地图属性相同的方式访问资源包属性可能值得一个功能请求。

因此,一种可能的解决方案是将您需要的资源值复制到地图中。以下适用于您的原始属性文件:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.util.HashMap?>

<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>


<VBox xmlns:fx="http://javafx.com/fxml/1">

    <fx:define>
        <HashMap fx:id="resourceAccess"
            labelTotal="%label.total"
        />              
    </fx:define>

    <Label text="${resourceAccess.labelTotal + ':'}" />

</VBox>

请注意,您可以根据需要在同一张地图中添加任意数量的属性,只需添加额外的属性即可。这感觉有点做作,但确实有效。

您也可以在加载 FXML 时在 Java 代码中执行此操作:

    ResourceBundle resourceBundle = ResourceBundle.getBundle(...);

    FXMLLoader loader = new FXMLLoader(getClass().getResource(...), resourceBundle);

    Map<String, Object> resourceAccess = new HashMap<>();
    for (String key : resourceBundle.keySet()) {
        resourceAccess.put(key, resourceBundle.getObject(key));
    }
    loader.getNamespace().put("resourceAccess", resourceAccess);

    Parent root = loader.load() ;

然后是 FXML

<Label text="${resourceAccess.labelTotal + ':'}" />

将在没有 <fx:define> 块的情况下工作。不过,此解决方案再次禁止在资源键中使用 .(或者至少您必须将它们转换为 Java 代码中的其他内容:resourceAccess.put(key.replaceAll("\.","_"), resourceBundle.getObject(key)); 或类似代码)。

目前尚不能立即看出其中的任何一个都比(可能更明显的)解决方法更好:

<HBox><Label text="%label.total"/><Label text=":"/></HBox>