问题描述
我需要本地化JavaFX内置控件。在拼图之前,有很多方法可以实现这一点:
- 必须将其他properties file放入
com.sun.javafx...
包装中 - 通过反射API,如显示的here
这两种方法均与Java模块不兼容,因为com/sun/javafx/scene/control/*
不是公共API的一部分,并且即使它们属于不同的项目,也无法创建两个具有相同名称的包。 / p>
是否有机会破解此问题以访问内部软件包?更具体地说,是ControlResources类加载器。
相关问题:
解决方法
好吧,我整天都在研究这个话题。
简短的回答:是不可能的。
长答案
您可以使用add-exports
和add-opens
来访问com.sun.javafx.scene.control.skin.resources
,但这仅在不使用命名模块的情况下才有效,换句话说,您的应用不得模块化。
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<configuration>
<mainClass>${bld.mainClass}</mainClass>
<executable>${java.home}/bin/java</executable>
<options>
<option>--add-exports</option>
<option>javafx.controls/com.sun.javafx.scene.control.skin.resources=app.module</option>
<option>--add-opens</option>
<option>javafx.controls/com.sun.javafx.scene.control.skin.resources=app.module</option>
</options>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>--add-exports</arg>
<arg>javafx.controls/com.sun.javafx.scene.control.skin.resources=app.module</arg>
<arg>--add-opens</arg>
<arg>javafx.controls/com.sun.javafx.scene.control.skin.resources=app.module</arg>
</compilerArgs>
</configuration>
</plugin>
如果您的应用是模块化的,您会得到的。
Caused by: java.lang.UnsupportedOperationException: ResourceBundle.Control not supported in named modules
at java.base/java.util.ResourceBundle.checkNamedModule(ResourceBundle.java:1547)
at java.base/java.util.ResourceBundle.getBundle(ResourceBundle.java:1508)
这是因为访问另一模块中资源的唯一方法是SPI(docs here)。 OpenJFX没有实现ResourceBundleProvider
来提供对控件国际化的访问,因为它是内部API的一部分。
因此,只有OpenJFX开发人员才能解决此问题,但是从最近的OpenJFX变更日志来看,他们高度专注于修正错别字,而不是功能。