2010-09-15 48 views
5

有许多关于使用Java ResourceBundles以多种语言提供UI的教程。但是,关于与翻译公司的典型互动,我似乎无法找到答案,因此存在流程问题。典型的java i18n进程 - 将资源文件发送给需翻译的翻译公司

假设例如我不知道法国人,需要聘请翻译公司获得的翻译我的应用程序,我会送他们

  1. 默认的资源属性文件“whatever_en_US.properties”包括关键和英文值,并取回“whatever_fr_FR.properties”?
  2. “whatever_fr_FR.properties”包含空值和“whatever_en_US.properties”以供参考?
  3. 其他一些组合?

回答

4

由于你的问题是关于一个过程而不是技术,我会尽力给你一个彻底的解释。假设您的应用程序没有以前的翻译,理想的过程应该如下所示:

  1. 发送英文文件进行翻译。根据与翻译承包商之间的协议,你可以使用:

    • 你的默认属性文件(你将负责正确地对其进行重命名)含
    • 的Excell电子表格键,英语短语和空列翻译
    • Gettext的* .po文件(S)如果你要当您收到Fi来使用gettext
    • 翻译记忆文件(S)(即TRADOS * .tmx文件)
  2. 您将这些翻译放入产品中,创建本地化版本并进行测试。当然,会有一些用户界面问题。其中一些可以自行修复,有些需要额外翻译(如硬编码字符串),其他翻译需要缩短翻译。再次,您将聘请翻译承包商并为他们提供需要(重新)翻译的字符串。你可以在这里使用电子表格(假设没有太多需要翻译的字符串)。

  3. 如果你想同时发布(所有语言一次),你需要提前搞翻译。由于UI字符串会发生变化(假设没有硬UI冻结期或翻译冻结期),您必须更新翻译。在这种情况下,您需要为已翻译的文件提供需要翻译的字符串(英文)。如果变化非常小,您只能发送英文字符串并手动合并翻译,否则最好使用某种翻译记忆库交换格式(gettext * .po's或trados * .tmx's在这里很棒)。

  4. 翻译文件通常是不够的。由于通常没有给定上下文,不同的词语可能在目标语言中意味着不同的事物,所以会出现翻译错误。除非你知道语言,否则无法知道他们在哪里。这就是为什么您需要截取用户界面截图并将其发送出去以供审核(可以由您的翻译承包商或其他人根据质量要求进行审核)。

  5. 经审查后,您将需要申请转换的变化和测试用户界面问题...

这就是它,如果我们谈论的UI字符串翻译过程。但请注意,还有很多功能可以正确定位应用程序(文档,帮助文件,图标,颜色,声音等)。

+0

太棒了!我知道你在这里提出的很多东西,但是你已经通过组织它来澄清。希望未来的stackoverflowers会发现它很有用。 – jlarson 2010-09-16 13:18:23

2

要回答你的问题,我会选择(2)。

在实践中,我发现对我来说,使用别的东西而不是Java资源包要容易得多。

我个人使用不同的方式来处理这个。我使用gettext方式(在那里有一个名为GetTextResource.java的文件,您必须在应用程序中使用它才能从gettext扩展中受益 - 请参阅here)。

如果你对gettext很熟悉,你一定会发现这种方法更容易和实用。您只需向您的翻译人员提供po文件(可使用poedit进行编辑)。从po文件创建您将在您的应用程序中使用的java类(这是通过msgfmt完成的 - 为po文件的java编译指定参数)。使用xgettext命令(从命令行)可以很容易地更新Po文件。

当然,一切都在gettext manual之内。

优点:

  • 的gettext为您提供了一种选择复数形式[没有更多的消息,如: “删除N文件(S)”(其中N是一个数字) - 看到ngettext

  • 因为一旦你的java文件与新的令牌

  • 不需要访问使用一些宏每个字符串更新字符串翻译编写脚本的方法(如翻译(DELETE_BUTTON_MACRO))。你只写你这样的代码:

    package translateutil;   
    import gnu.gettext.GettextResource; 
    
    import java.util.ResourceBundle; 
    
    import java.util.Locale; 
    
    public class TranslateUtil 
    { 
    private static ResourceBundle myResources =null; 
    
    public static boolean init(Locale loc, String resourceName) 
    { 
        boolean bRet = true; 
        Locale.setDefault(loc); 
    
        try 
        { 
         myResources = ResourceBundle.getBundle(resourceName); 
    
         System.out.printf( _("Current language: %s\n"), 
              Locale.getDefault().getDisplayName()); 
    
         System.out.printf( _("%s resource found\n"), 
              myResources.getClass().getName()); 
        } 
        catch(Exception e) 
        { 
         // let the application go on in English in case the ResourceBundle 
         // was not found. Notify about the error 
         bRet = false; 
         System.out.println(e.toString()); 
         myResources = null; 
        } 
    
        return bRet; 
    } 
    
    
    public static String _(String str) 
    { 
        if (myResources == null) 
        { 
         return str; 
        } 
        { 
         return GettextResource.gettext(myResources, str); 
        } 
    } 
    
    public static String _Plural(String singular, String plural, long param) 
    { 
        if (myResources == null) 
        { 
         if (param == 1) 
         { 
          return singular; 
         } 
         else 
         { 
          return plural; 
         } 
        } 
        else 
        { 
         return GettextResource.ngettext(myResources, singular, plural, param); 
        } 
    } 
    } 
    

下面是一个简单

// example 
    // similar for plural 

    import static translateutil.TranslateUtil._; 

    System.out.println(_("The english text")); 

不管你的选择是什么:祝你好运!

+0

谢谢大家了完整的答案......我其实用java把ResourceBundle而是一个专有的解决方案不_really_,但想通询问把ResourceBundle简化问题。 – jlarson 2010-09-15 22:16:44