我的“Messages.properties”文件中有一个属性,它有一个使用数字格式的参数:
my.message=File exceeds {0,number,0.0}MB.
当我运行gwt:i18n
Maven目标时,它会根据我的“Messages.properties”文件中的属性生成Messages
接口(正常情况下):
public interface Messages extends com.google.gwt.i18n.client.Messages {
//...
@DefaultMessage("File exceeds {0,number,0.0}MB.")
@Key("my.message")
String my_message(String arg0);
//...
}
问题是方法参数是String
。当我运行应用程序时,它给了我一个错误,因为message参数需要一个数字,但提供了一个String(错误消息是,“只有数字子类可以被格式化为数字”)。
如何配置Maven将此参数更改为数字(如float
或Number
)?感谢。
答案 0 :(得分:2)
鉴于上述讨论,我决定补充我以前的答案。 首先,据我所知,你无法使用现有的i18n Maven目标(和GWT的I18NCreator)来做所谓的事情。 其次,在对我建议的Generator解决方案进行了更多研究之后,我发现:
就个人而言,我只会编写和维护我的属性文件以及手动镜像它的界面。生成器将始终查看属性文件并生成与属性对应的方法(根据实际消息需要任何参数),因此如果您编写的接口反映了属性文件,则生成器生成的类将始终正确实施。
答案 1 :(得分:1)
在我看来,GWT I18NCreator不支持此功能(这是maven i18n目标所称的)。你必须编写自己的Generator才能做到这一点。 我写了几个发电机,并没有你想象的那么难。 在您的情况下,您可能希望编写一个生成器,该生成器创建类似于GWT的消息的接口实例(但您可以使用自己的消息)但在解码消息时具有所需的附加功能。 以下如何使用小指南可能会对您有所帮助,因为它似乎也是我所做的,它也起作用:
http://groups.google.com/group/Google-Web-Toolkit/msg/ae249ea67c2c3435?pli=1
我发现编写GWT生成器的最简单方法是实际编写一个测试类,其中包含您希望在IDE中生成的代码(并借助自动完成,语法检查等),然后再过去/适应这样的作家调用:
writer.println("public void doSomething() { /* implement */ }");
并且不要忘记告诉你的模块(module.gwt.xml文件)需要生成哪个接口,以及使用哪个类:
<generate-with class="mycompany.utils.generators.MyGenerator">
<when-type-assignable class="mycompany.messages.MyCoolPropertiesReader" />
</generate-with>
在Generator代码中,您可以使用Java及其所有强大功能(不限于GWT可翻译代码),因此实现您想要的并不困难。在客户端代码中,您可以执行以下操作:
public interface MyCoolPropertiesReader {
public String getMessage(String propKey, Object... parameters);
}
public class MyClientSideClass {
MyCoolPropertiesReader reader = GWT.create(MyCoolPropertiesReader.class);
String msg = reader.getMessage("my.message", 10);
// do more work
}
我写的一个测试生成器(一个GWT“反射”的getter和setter,就像这样)看起来像这样:
public class TestGenerator extends Generator {
@Override
public String generate(TreeLogger logger, GeneratorContext context,
String typeName) throws UnableToCompleteException {
try {
TypeOracle oracle = context.getTypeOracle();
JClassType requestedClass = oracle.getType(typeName);
String packageName = requestedClass.getPackage().getName();
String simpleClassName = requestedClass.getSimpleSourceName();
String proxyClassName = simpleClassName + "GetterAndSetter";
String qualifiedProxyClassName = packageName + "." + proxyClassName;
System.out.println("Created a class called: " + qualifiedProxyClassName);
PrintWriter printWriter = context.tryCreate(logger, packageName, className);
if (printWriter == null) return null;
ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory(packageName, className);
composerFactory.addImport("test.project.shared.GetterAndSetter");
composerFactory.addImplementedInterface("GetterAndSetter<" + underlyingTypeName + ">");
SourceWriter writer = composerFactory.createSourceWriter(context, printWriter);
if (writer != null) {
JField[] fields = requestedClass.getFields();
for (JField field : fields) {
createSetterMethodForField(typeName, writer, field);
}
writer.indent();
writer.println("public void set(" + typeName + " target, String path, Object value) {");
writer.indent();
createIfBlockForFields(writer, fields, true);
writer.outdent();
writer.println("}");
writer.println();
writer.println("public <K> K get(" + typeName + " target, String path) {");
writer.indent();
createIfBlockForFields(writer, fields, false);
writer.outdent();
writer.println("}");
writer.println();
writer.outdent();
writer.commit(logger);
}
return packageName + "." + proxyClassName;
} catch(NotFoundException nfe) {
throw new UnableToCompleteException();
}
}
}
我希望这会对你有所帮助。