5

有大量关于使用 Java ResourceBundles 以多种语言提供 UI 的教程。但是,关于与翻译公司的典型互动,有一个流程问题,我似乎无法找到答案。

例如,假设我不懂法语,并且需要聘请翻译公司为我的应用程序获取翻译,我会发送给他们吗

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

2 回答 2

4

由于您的问题是关于过程而不是技术,因此我将尽力为您提供详尽的解释。假设您有没有以前翻译的应用程序,理想的过程应该如下所示:

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

    • 您的默认属性文件(您将负责正确重命名它们)
    • Excel 电子表格包含键、英文短语和用于翻译的空列
    • Gettext *.po 文件(如果您要使用 gettext)
    • 翻译记忆库文件(即 Trados *.tmx 文件)
  2. 当您收到文件返回时,您将这些翻译放入产品中,创建本地化版本并对其进行测试。当然,会有一些 UI 问题。其中一些您可以自己修复,一些需要额外的翻译(如硬编码字符串),另一些则需要缩短翻译。同样,您将聘请翻译承包商并向他们提供需要(重新)翻译的字符串。您可以在此处使用电子表格(前提是需要翻译的字符串不多)。

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

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

  5. 审核后,您将需要应用翻译更改并测试 UI 问题...

就是这样,如果我们谈论的是 UI 字符串翻译过程。但请注意,正确本地化应用程序还有很多其他内容(文档、帮助文件、图标、颜色、声音......)。

于 2010-09-16T07:07:46.630 回答
2

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

在实践中,我发现对我来说使用其他东西比使用 Java 资源包要容易得多。

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

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

当然,一切都在gettext 手册中。

优点:

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

  • 使用新标记更新 java 文件后用于翻译字符串的脚本化方法

  • 无需使用某些宏(如 Translate(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"));

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

于 2010-09-15T22:13:36.523 回答