| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| |
| = 国际化 GUI 窗体 |
| :jbake-type: tutorial |
| :jbake-tags: tutorials |
| :jbake-status: published |
| :icons: font |
| :syntax: true |
| :source-highlighter: pygments |
| :toc: left |
| :toc-title: |
| :description: 国际化 GUI 窗体 - Apache NetBeans |
| :keywords: Apache NetBeans, Tutorials, 国际化 GUI 窗体 |
| |
| 本教程将指导您完成在 NetBeans IDE 中进行国际化的一些基本步骤。我们将对一个窗体设置国际化,并在稍后设计该窗体。接下来,我们会国际化整个项目,该项目在几个不同的包中包含若干窗体。您可以通过指定自动国际化或使用专门的向导来国际化应用程序。 |
| |
| *预计时间:30 分钟* |
| |
| |
| image::images/netbeans-stamp-80-74-73.png[title="此页上的内容适用于 NetBeans IDE 7.0 和更高版本"] |
| |
| |
| *要学完本教程,您需要具备以下软件和资源。* |
| |
| |=== |
| |软件或资源 |要求的版本 |
| |
| |link:http://netbeans.org/downloads/index.html[+NetBeans IDE+] |版本 7.0 或更高版本 |
| |
| |link:http://www.oracle.com/technetwork/java/javase/downloads/index.html[+Java 开发工具包 (JDK)+] |版本 6、7 或 8 |
| |=== |
| |
| |
| == 国际化的原理 |
| |
| 通过进行国际化,可以根据不同的语言和地区来改编应用程序,而无需进行工程更改或重新编译。国际化程序允许将文本性元素(如状态消息和 GUI 组件标签)存储在源代码外部并对其进行动态检索,而不是在程序中对其进行固定编码。 |
| |
| 通常将国际化字符串以键/值对的形式存储在属性文件中。键是程序用于检索文本的标识符,而值是实际文本。对于转换程序所用的每种语言环境(或语言),都将创建一个属性文件。键在每种语言环境中都相同,只是字符串不同。 |
| |
| IDE 提供了用于执行下列各项操作的工具: |
| |
| * 在创建 GUI 窗体或 Java 程序时插入国际化字符串 |
| * 将单个文件或文件组中的所有固定编码字符串替换为国际化字符串 |
| |
| |
| == 在设计时国际化 GUI 窗体 |
| |
| 在此练习中,我们将打开 Java 应用程序演示项目,其中包含使用 GUI 构建器创建的常用查找对话框。接下来,我们将对窗体 FindDialog.java 启用自动国际化。为了测试已国际化的 GUI 窗体,我们将在属性文件中添加一种新的语言环境,然后在非默认语言环境下运行该窗体。 |
| |
| |
| === 打开示例项目 |
| |
| 1. 下载 link:https://netbeans.org/files/documents/4/770/InternationalizeDemo.zip[+InternationalizeDemo.zip+] 项目并将其解压缩到您计算机上的任何位置。 |
| 2. 选择 "File"(文件)> "Open Project"(打开项目),导航至您在上一步中解压缩的 ``InternationalizeDemo`` 项目,然后单击 "Open"(打开)。项目文件夹可能包含在同样名为 ``InternationalizeDemo`` 的文件夹中。 |
| 3. 展开 "Source Packages"(源包)> "Demo"(演示),然后双击 ``FindDialog.java`` 。将在 GUI 构建器中打开样例窗体。 |
| |
| image::images/finddialog_ai18n.png[] |
| |
| |
| === 启用自动国际化 |
| |
| 1. 在 "Navigator"(导航器)窗口中选择根节点(名为 ``Form FindDialog`` (窗体 FindDialog))。 |
| |
| image::images/navigator.png[] |
| |
| |
| |
| . 在 "Properties"(属性)窗口中,选中 "Automatic Internationalization"(自动国际化)属性中的复选框。 |
| |
| image::images/properties.png[] |
| |
| |
| |
| . 在 "GUI Form Format Upgrade"(GUI 窗体格式升级)对话框中,单击 "Upgrade"(升级)。 |
| |
| 如果选中该复选框,则 IDE 将按照 ``Properties Bundle File`` (属性包文件)属性中的设置在 ``demo`` 包中创建 ``Bundle.properties`` 文件。 |
| |
| image::images/bundle_new.png[] |
| |
| 如果您需要在其他位置创建 ``Bundle.properties`` 文件,则可以单击 "Properties Bundle File"(属性包文件)右侧的省略号 (...) 按钮,然后选择一个位置,或者直接在该属性的文本字段中键入路径。 |
| |
| |
| |
| . 在 "Projects"(项目)窗口中,双击 ``Bundle.properties`` 节点,或者右键单击该节点,然后选择 "Edit"(编辑)。 |
| |
| 将在源代码编辑器中打开该属性文件。正如您所看到的,将为窗体 ``FindDialog.java`` 生成所有相应的键和值。(每个键的名称是从窗体文件名和组件变量名派生的。例如,键 ``FindDialog.jLabel1.text`` 是为窗体文件 ``FindDialog`` 中包含的变量名为 ``jLabel1`` 的组件生成的。在此示例中,值 ``jLabel1`` 表示组件的 "text" 属性。 |
| |
| |
| |
| . 关闭 ``Bundle.properties`` 文件。 |
| |
| |
| === 国际化各个 GUI 组件 |
| |
| 现在,我们将使用 GUI 构建器为窗体中的 JLabel 和 JButton 输入国际化字符串。 |
| |
| 1. 在设计区域中选择相应的 GUI 组件(例如 ``jLabel1`` )。 |
| 2. 在 "Properties"(属性)窗口中,单击 "text" 属性的省略号 (...) 按钮。 |
| |
| *注:*您还可以对具有字符串值的其他属性进行国际化,例如助记符、可访问的名称、可访问的描述符和工具提示。 |
| |
| |
| |
| . 属性编辑器将切换至资源包模式。检查 "Bundle Name"(包名)字段是否设置为 ``demo.Bundle`` ,以及 "Key"(键)字段是否包含字符串 ``FindDialog.jLabel1.text`` 。 |
| |
| |
| . 在 "Value"(值)字段中键入 ``Find What:`` 。 |
| |
| |
| . 单击 "OK"(确定)。 |
| |
| 对所有组件重复执行以上步骤,使该窗体如下图所示: |
| |
| [.feature] |
| -- |
| image::images/finddialog_new_small.png[role="left", link="images/finddialog_new.png"] |
| -- |
| |
| *注:*可使用更便捷的方法来完成步骤 1 至 5 的操作:只需在 "Design"(设计)视图中双击 ``jLabel1`` ,将其文本从 ``jLabel1`` 更改为 ``Find What:`` ,然后按 Enter 键即可。其结果与以上提供的步骤所得到的结果相同。 |
| |
| 要使组件的宽度相同,请完成以下步骤: |
| |
| 1. 按住 Ctrl 键单击窗体中的所有八个 jCheckBox 将它们选中。 |
| 2. 在选中了这些 jCheckBox 的情况下,右键单击其中任何一个,然后从弹出式菜单中选择 "Same Size"(相同大小)> "Same Width"(相同宽度)。 |
| 3. 对三个 jButton 执行步骤 1 至 2 的操作。 |
| |
| |
| === 添加新语言环境 |
| |
| 1. 在 "Navigator"(导航器)窗口中选择根节点( ``Form FindDialog`` (窗体 FindDialog)节点)。 |
| 2. 在 "Properties"(属性)窗口中,单击 "Design Locale"(设计语言环境)属性的省略号 (...) 按钮。 |
| 3. 在 "New Locale"(新建语言环境)对话框中,从 ``Predefined Locales:`` (预定义的语言环境:)组合框中选择 ``es_ES`` 。 |
| 4. 单击 "OK"(确定)。 |
| |
| ``Bundle.properties`` 节点下将显示新语言环境,如下所示: |
| |
| image::images/addlocale_new.png[] |
| |
| |
| |
| . 在 "Projects"(项目)窗口中,右键单击 ``Bundle.properties`` ,然后选择 "Open"(打开)。 |
| |
| |
| . 将相应表列中的各条消息转换为新语言(例如西班牙语),如下所示: |
| |
| [.feature] |
| -- |
| image::images/bundles_new_small.png[role="left", link="images/bundles_new.png"] |
| -- |
| |
| |
| |
| . 按 Ctrl-S 组合键保存所做的编辑。 |
| |
| |
| . 选择 ``FindDialog.java`` 标签,以显示要国际化的窗体。 |
| |
| |
| . 在 "Navigator"(导航器)窗口中右键单击根节点,然后选择 "Reload Form"(重新加载窗体)(或者,按 Ctrl-R 组合键)。 |
| |
| |
| . 在显示的 "Question"(问题)对话框中单击 "Save"(保存)。 |
| 将重新打开该窗体,并在设计区域中加载西班牙语语言环境,如下所示: |
| |
| [.feature] |
| -- |
| image::images/finddialog_es_new_small.png[role="left", link="images/finddialog_es_new.png"] |
| -- |
| |
| |
| === 测试非默认语言环境 |
| |
| 1. 在 "Projects"(项目)窗口中,右键单击 InternationalizeDemo 项目,然后选择 "Properties"(属性)。 |
| 2. 在 "Categories"(类别)窗格中,选择 "Run"(运行)节点。 |
| 3. 在 "VM Options"(VM 选项)字段中输入 ``-Duser.language=es -Duser.country=ES`` 。 |
| |
| [.feature] |
| -- |
| image::images/prjproperties_small.png[role="left", link="images/prjproperties.png"] |
| -- |
| |
| |
| |
| . 单击 "OK"(确定)。 |
| |
| |
| . 右键单击 "InternationalizeDemo" 项目,然后选择 "Run"(运行)。 |
| |
| IDE 将在西班牙语语言环境中运行 ``FindDialog`` 对话框,如下所示。 |
| |
| [.feature] |
| -- |
| image::images/run_small.png[role="left", link="images/run.png"] |
| -- |
| |
| |
| == 国际化整个项目 |
| |
| 通常,我们在默认语言环境中拥有几个文件,并且系统要求我们改编这些文件,以便将其转换为其他语言。国际化向导是用于执行此任务的最佳工具,因为它可以一次国际化多个文件。我们将在 GUI 窗体示例项目中演示此功能,该项目包含在link:quickstart-gui.html[+设计 Swing GUI+] 教程中创建的窗体。 |
| |
| |
| === 创建样例项目 |
| |
| 1. 选择 "File"(文件)> "New Project"(新建项目),或者单击 IDE 工具栏中的 "New Project"(新建项目)图标。 |
| 2. 在 "Categories"(类别)窗格中,选择 "Samples"(样例)> "Java" 节点。在 "Projects"(项目)窗格中,选择 "GUI Form Examples"(GUI 窗体示例)。单击 "Next"(下一步)。 |
| 3. 在 "Project Name"(项目名称)字段中输入 ``GUIFormExamples`` ,然后指定项目位置(例如 ``/space/projects`` )。 |
| 4. 单击 "Finish"(完成)。 |
| |
| image::images/formexamples.png[] |
| |
| |
| === 准备属性文件 |
| |
| 1. 选择 "File"(文件)> "New File"(新建文件),或者单击 IDE 工具栏中的 "New File"(新建文件)图标。 |
| 2. 在 "Categories"(类别)窗格中,选择 "Other"(其他)节点;在 "File Types"(文件类型)窗格中,选择 "Properties File"(属性文件)。单击 "Next"(下一步)。 |
| 3. 在 "File Name"(文件名)字段中输入 ``ContactEditor`` 。 |
| 4. 单击 "Browse"(浏览),然后在 "Browse Folders"(浏览文件夹)对话框中,将 ``GUIFormExamples/src/examples`` 文件夹指定为文件位置。 |
| 5. 单击 "Select Folder"(选择文件夹)。 |
| 6. 单击 "Finish"(完成)。 |
| |
| IDE 将创建 ``ContactEditor.properties`` 文件并在源代码编辑器中将其打开。 |
| |
| 重复上述步骤以创建另一个 ``Antenna.properties`` 文件。 |
| |
| image::images/ceprjprops.png[] |
| |
| |
| === 调用国际化向导 |
| |
| 1. 在主菜单中,选择 "Tools"(工具)> "Internationalization"(国际化)> "Internationalization Wizard"(国际化向导)。 |
| 2. 在该向导的第一页上,单击 "Add Source(s)"(添加源)。 |
| 3. 在 "Select Sources"(选择源)对话框中,展开 ``Source Packages`` (源包)> ``Examples`` (示例)节点,然后按住 Ctrl 键单击 ``Antenna.java`` 、 ``ContactEditor.java`` 和 ``Find.java`` 文件将其选中。 |
| 4. 单击 "OK"(确定)。 |
| |
| 源文件将显示在该向导的第一页中,如下所示: |
| |
| [.feature] |
| -- |
| image::images/i18nwizardone_small.png[role="left", link="images/i18nwizardone.png"] |
| -- |
| |
| |
| |
| . 为了便于演示,选择 ``examples.Find`` ,然后单击 "Remove Source(s)"(删除源)按钮。 |
| |
| |
| . 单击 "Next"(下一步)。 |
| |
| |
| . 检查国际化向导是否提供了正确的属性文件 ``examples.Antenna`` 和 ``examples.ContactEditor`` 。如果未提供,请使用 "Select Resource"(选择资源)按钮来选择正确的属性文件。 |
| |
| [.feature] |
| -- |
| image::images/i18nwizardtwo_small.png[role="left", link="images/i18nwizardtwo.png"] |
| -- |
| |
| |
| |
| . 单击 "Next"(下一步)。 |
| |
| |
| . 跳过该向导的第 3 页(因为您不打算创建任何字段并修改其他值),然后单击 "Next"(下一步)。 |
| |
| |
| . 所有固定编码字符串都将显示在国际化向导的最后一步中,您可以在该步中确定将哪些字符串包含在属性文件中(使用复选框)。您也可以进一步定制各个键、值、注释和替换字符串的格式,方法是单击字符串的省略号 (...) 按钮。 |
| |
| [.feature] |
| -- |
| image::images/i18nwizardthree_small.png[role="left", link="images/i18nwizardthree.png"] |
| -- |
| |
| |
| |
| . 单击 "Finish"(完成)。 |
| |
| 现在,已完成源代码的国际化,接下来可以按照先前所述<<newlocale,添加>>和<<testlocale,测试>>其他语言环境。 |
| |
| |
| == 国际化单个窗体 |
| |
| 使用自动国际化功能是国际化 GUI 窗体的最简便方法。但是,如果您没有安装更新包,或者还希望国际化不是由窗体编辑器生成的代码,则可以使用 "Internationalize"(国际化)窗口。(此功能可处理任何 ``.java`` 文件,而不仅仅是通过窗体编辑器创建的文件)。下面的示例使用了 "Internationalization"(国际化)窗口,该窗口是 NetBeans IDE 默认安装的一部分。 |
| |
| 在此最后练习中,我们将重用 GUI 窗体示例项目并国际化 Find.java 窗体(在先前的练习中排除了该窗体)。我们将调用 "Internationalize"(国际化)对话框来替换此文件中的所有固定编码字符串。最后,我们将简要演示如何在编写程序时将国际化字符串插入源代码中。 |
| |
| |
| === 使用 "Internationalize"(国际化)对话框 |
| |
| 1. 在 "Projects"(项目)窗口中,选择 ``Find.java`` ,然后从主菜单中选择 "Tools"(工具)> "Internationalization"(国际化)> "Internationalize"(国际化)。 |
| |
| IDE 将显示 "Internationalization"(国际化)对话框,并预先填写 ``Find.java`` 源代码中的第一个固定编码字符串。 |
| |
| |
| |
| . 单击 "Select"(选择)以选择特定的属性文件,或者创建新文件。 |
| |
| |
| . 在 "Select Resource Bundle"(选择资源包)对话框中,在 "File Name"(文件名)文本字段中输入 ``Find.properties`` ,单击 "Create New"(新建),然后单击 "OK"(确定)。 |
| |
| |
| . 您可以修改替换字符串的格式、键、值或注释(如有必要)。我们将仅保留默认值。 |
| |
| |
| . 单击 "Replace"(替换)以确认更改,并将焦点移到下一个固定编码字符串上。 |
| |
| 如果不需要替换固定编码字符串,请单击 "Skip"(跳过)按钮。 |
| |
| [.feature] |
| -- |
| image::images/i18ndialog_small.png[role="left", link="images/i18ndialog.png"] |
| -- |
| |
| |
| === 插入单个国际化字符串 |
| |
| 1. 在 "Projects"(项目)窗口中,右键单击 ``Find.java`` ,然后选择 "Edit"(编辑)。 |
| |
| IDE 将在源代码编辑器中打开 ``Find.java`` 文件。 |
| |
| |
| |
| . 滚动查看源代码并查找 main 方法。 |
| |
| |
| . 在 main 方法中插入以下用粗体显示的行: |
| |
| [source,xml] |
| ---- |
| |
| public static void main(String args[]) { |
| /* Set the Nimbus look and feel */ |
| //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> |
| /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. |
| * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html |
| */ |
| try { |
| javax.swing.UIManager.LookAndFeelInfo[] installedLookAndFeels=javax.swing.UIManager.getInstalledLookAndFeels(); |
| for (int idx=0; idx<installedLookAndFeels.length; idx++) |
| if ("Nimbus".equals(installedLookAndFeels[idx].getName())) { |
| javax.swing.UIManager.setLookAndFeel(installedLookAndFeels[idx].getClassName()); |
| break; |
| } |
| } catch (ClassNotFoundException ex) { |
| java.util.logging.Logger.getLogger(Find.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); |
| } catch (InstantiationException ex) { |
| java.util.logging.Logger.getLogger(Find.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); |
| } catch (IllegalAccessException ex) { |
| java.util.logging.Logger.getLogger(Find.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); |
| } catch (javax.swing.UnsupportedLookAndFeelException ex) { |
| java.util.logging.Logger.getLogger(Find.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); |
| } |
| //</editor-fold> |
| *System.out.println();* |
| /* Create and display the form */ |
| java.awt.EventQueue.invokeLater(new Runnable() { |
| public void run() { |
| new Find().setVisible(true); |
| } |
| }); |
| } |
| ---- |
| |
| |
| . 将鼠标光标放在 ``System.out.println();`` 的圆括号内,以便作为参数插入国际化字符串。 |
| |
| |
| . 按 Ctrl-Shift-J 组合键调用 "Insert Internationalized String"(插入国际化字符串)对话框(也可以从主菜单中选择 "Tools"(工具)> "Internationalization"(国际化)> "Insert Internationalized String"(插入国际化字符串))。 |
| |
| |
| . 对于 "Bundle Name"(包名),单击 "Select"(选择)按钮,选择 ``"Source Packages"(源包)> "Examples"(样例)`` 文件夹,然后在 "File Name"(文件名)文本字段中输入 ``Find`` 作为包名。然后,单击 "OK"(确定)。 |
| "Insert Internationalized String"(插入国际化字符串)对话框的 "Bundle Name"(包名称)字段显示 ``examples.Find`` 。 |
| |
| |
| . 在 "Key"(键)下拉框中键入 ``Start`` ,并在 "Value"(值)字段中键入 ``Start Find Dialog`` 。然后,单击 "OK"(确定)。 |
| |
| image::images/insi18nstring.png[] |
| |
| |
| |
| . IDE 将插入国际化字符串: |
| |
| [source,xml] |
| ---- |
| |
| public static void main(String args[]) { |
| /* Set the Nimbus look and feel */ |
| //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> |
| /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. |
| * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html |
| */ |
| try { |
| javax.swing.UIManager.LookAndFeelInfo[] installedLookAndFeels=javax.swing.UIManager.getInstalledLookAndFeels(); |
| for (int idx=0; idx<installedLookAndFeels.length; idx++) |
| if ("Nimbus".equals(installedLookAndFeels[idx].getName())) { |
| javax.swing.UIManager.setLookAndFeel(installedLookAndFeels[idx].getClassName()); |
| break; |
| } |
| } catch (ClassNotFoundException ex) { |
| java.util.logging.Logger.getLogger(Find.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); |
| } catch (InstantiationException ex) { |
| java.util.logging.Logger.getLogger(Find.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); |
| } catch (IllegalAccessException ex) { |
| java.util.logging.Logger.getLogger(Find.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); |
| } catch (javax.swing.UnsupportedLookAndFeelException ex) { |
| java.util.logging.Logger.getLogger(Find.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); |
| } |
| //</editor-fold> |
| * System.out.println(java.util.ResourceBundle.getBundle("examples/Find").getString("Start"));* |
| /* Create and display the form */ |
| java.awt.EventQueue.invokeLater(new Runnable() { |
| public void run() { |
| new Find().setVisible(true); |
| } |
| }); |
| } |
| ---- |
| |
| |
| link:/about/contact_form.html?to=3&subject=Feedback:Internationalizing%20a%20GUI%20Form%20in%20NetBeans%20IDE[+发送有关此教程的反馈意见+] |
| |
| |
| |
| == 另请参见 |
| |
| 有关更多信息,请参见以下链接: |
| |
| * _使用 NetBeans IDE 开发应用程序_中的link:http://www.oracle.com/pls/topic/lookup?ctx=nb8000&id=NBDAG920[+实现 Java GUI+] |
| * link:../../trails/matisse.html[+Java GUI 应用程序学习资源+] |
| * link:quickstart-gui.html[+设计 Swing GUI+] |
| * link:http://wiki.netbeans.org/wiki/view/NetBeansUserFAQ[+GUI 构建器常见问题解答+] |