一、国际化编程的本质及原理分析

  • 一套软件,多个语言包

Java是第一个设计成支持国际化的编程语言

  • 重点在于如下两个类;
  • java.util.ResourceBundle 用于加载一个语言_国家包
  • java.util.Locale 定义一个语言_国家
  • 语言 zh,en等,国家/地区CN,US
  • 语言文件
  • 就是一个properties文件
  • Properties 类在加载.proerties文件时使用的iso-8859-1的编码,所以由中文时必须进行native2ascii进行转义。
  • 包含键值对,形式为key=value,例如age=20;name=中国
  • 存储编码必须为ASCII编码,如果是ASCII以外的文字,则必须使用native2ascii.exe(%JAVA_HOME%/bin目录下)进行转码为Unicode,命令格式如下:
    native2ascii xxx.properties xxx_语言_国家.properties

命名规则:

  • 包名_语言_国家地区.properties (语言和国家/地区可选)
  • message.properties
  • message.zh.properties
  • message.zh_CN.properties

二、代码实践

项目文件结构如下图:

请先忽略其中的resource文件夹,com目录是编译Main.java时自动生成的class包目录,重点先关注Main.java文件,其中Main.java文件的内容如下:

package com.cholen;import java.util.Locale;
import java.util.ResourceBundle;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;class MainWindow extends JFrame implements ActionListener{private JLabel jlbAccount;private JLabel jlbPassword;private JTextField jtfAccount;private JTextField jtfPassword;private JButton btnLogin;private JButton btnCancel;private JPanel mainPanel;private JMenuBar jMenuBar;private JMenu jmLanguage;private JMenuItem jmiZH;private JMenuItem jmiEN;private static Locale locale;private static ResourceBundle bundle;public MainWindow(){mainPanel = new JPanel();mainPanel.setLayout(new GridLayout(3, 2, 5, 5));jlbAccount = new JLabel();jlbAccount.setHorizontalAlignment(JLabel.CENTER);jlbAccount.setVerticalAlignment(JLabel.CENTER);jlbPassword = new JLabel();jlbPassword.setHorizontalAlignment(JLabel.CENTER);jlbAccount.setVerticalAlignment(JLabel.CENTER);jtfAccount = new JTextField();jtfPassword = new JTextField();btnLogin = new JButton();btnCancel = new JButton();jMenuBar = new JMenuBar();jmLanguage = new JMenu();jmiZH = new JMenuItem();jmiEN = new JMenuItem();jmLanguage.add(jmiZH);jmLanguage.addSeparator();jmLanguage.add(jmiEN);jMenuBar.add(jmLanguage);mainPanel.add(jlbAccount);mainPanel.add(jtfAccount);mainPanel.add(jlbPassword);mainPanel.add(jtfPassword);mainPanel.add(btnLogin);mainPanel.add(btnCancel);setLanguage(locale);jmiEN.addActionListener(this);jmiZH.addActionListener(this);this.setJMenuBar(jMenuBar);this.getContentPane().add(mainPanel);this.setSize(512, 600);this.setVisible(true);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}@Overridepublic void actionPerformed(ActionEvent e) {if(e.getSource()==jmiZH){locale = new Locale("zh", "CN");this.setLanguage(locale);}else if(e.getSource()==jmiEN){locale = new Locale("en", "US");this.setLanguage(locale);}}private void setLanguage(Locale locale){bundle = ResourceBundle.getBundle("messages", locale);this.setTitle(bundle.getString("mainWindowTitle"));jmLanguage.setText(bundle.getString("jmLanguage"));jmiZH.setText(bundle.getString("jmiZH"));jmiEN.setText(bundle.getString("jmiEN"));jlbAccount.setText(bundle.getString("jlbAccount"));jlbPassword.setText(bundle.getString("jlbPassword"));btnLogin.setText(bundle.getString("btnLogin"));btnCancel.setText(bundle.getString("btnCancel"));}static {// 取得系统默认的国家_语言环境locale = Locale.getDefault();}}
public class Main{public static void main(String[] args){new MainWindow();}
}

进入到Main.java所在的文件夹下,执行如下编译命令即可生成上述的com目录:

javac -d . Main.java

其中messages_zh_CN.properties原始内容如下:

jmLanguage=语言
jmiZH=中文
jmiEN=英文
jlbAccount=账号
jlbPassword=密码
btnLogin=登录
btnCancel=取消
mainWindowTitle=微信
  • 请务必在保存时将该文件保存为ascii类型

进入到message_zh_CN.properties文件所在的目录,接下来用native2ascii.exe进行转码,命令如下:

native2ascii message_zh_CN.properties message_zh_CN.properties
  • native2ascii的第一个参数是src文件名,第二个参数是out文件名

这里将输出和输入定为一样的,则原来的message_zh_CN.properties会被覆盖,被覆盖后的内容如下:

jmLanguage=\u8bed\u8a00
jmiZH=\u4e2d\u6587
jmiEN=\u82f1\u6587
jlbAccount=\u8d26\u53f7
jlbPassword=\u5bc6\u7801
btnLogin=\u767b\u5f55
btnCancel=\u53d6\u6d88
mainWindowTitle=\u5fae\u4fe1

其中message_en_US.properties的内容如下:

jmLanguage=language
jmiZH=Chinese
jmiEN=English
jlbAccount=account
jlbPassword=password
btnLogin=login
btnCancel=cancel
mainWindowTitle=WeChat
  • 由于其本身就是英文,所以不需要用native2ascii进行转码,但请务必在保存时选择保存为ascii类型

直接用java命令运行生成的com.cholen.Main.class 文件,效果图如下面视频所展示:

Java国际化编程效果展示 (中英文切换)

这里视频不清晰的话,请移步到下方链接地址:

https://www.bilibili.com/video/BV1hA41177Yv/

三、实践过程中的问题

3.1 问题提出

在开始编写代码时,我并没有将MainWindow类实现ActionListener接口,而是想到的是直接在构造函数中为菜单项 “中文”、“英文”(代码中的jmiZH、jmiEN)直接addActionListener实现语言_地区的转换,而本例由于要在addActionListener中调用该类的一个成员方法setLanguage(Locale locale), 由于此时构造函数没有执行完,对象还没有生成,所以这样的做法不成功

3.2 问题解决

让MainWindow这个类去实现ActionListener接口,并重写其中的actionPerformed(ActionEvent e)方法,如下:

 @Overridepublic void actionPerformed(ActionEvent e) {if(e.getSource()==jmiZH){locale = new Locale("zh", "CN");this.setLanguage(locale);}else if(e.getSource()==jmiEN){locale = new Locale("en", "US");this.setLanguage(locale);}}

务必在构造函数中为菜单项 “中文”、“英文”(代码中的jmiZH、jmiEN)添加事件监听,代码如下:

 jmiEN.addActionListener(this);jmiZH.addActionListener(this);

四、代码实践后的思考

4.1 关于.properties文件存放的路径问题

messages_en_US.properties和messages_zh_CN.properties文件目前必须放在类的顶级目录下,

  • 能否将其放在某个包下面,此时如何找到该资源文件?
  • 能否新建一个resource目录,再在resource目录下新建一个language目录,将其放在该目录下,此时如何找到该资源文件?

4.2 解决方案

4.2.1 可以将资源文件放在某个包下面,譬如我将其放在com包目录下,如下图展示:

那么此时源代码中的:

 bundle = ResourceBundle.getBundle("messages", locale);

这一行应改为:

 bundle = ResourceBundle.getBundle("com.messages", locale);

也就是说带上包名

4.2.2 可以将资源文件放在\resource\language目录下,如下图展示:


问题的关键就在于Java对于外部资源的访问,这是一个主题,值得弄懂学习,读者可以自行学习,我这里直接给出解决方案,自己写一个流将资源文件读入(请务必关注资源的路径问题)。

Java国际化编程之中英文切换相关推荐

  1. android中英文切换功能,Android开发之中英文切换

    这篇文章详细介绍了Android开发之中英文切换,文中穿插有实例代码和示例程序介绍的很详细,遇到同样问题的朋友可以参考一下,如果有更好的解决方法,请留言分享帮助更多的程序员. 首先配置文件的appli ...

  2. Android 国际化适配之中英文模式切换

    前言 最近在做一个app,要求有中文模式与英文模式,其实就是国际化适配了,这个不难但是感觉非常麻烦呀,先看下我写的简单例子,这样比较直观点: 接下来我介绍下如何去实现它: 布局文件中的Textview ...

  3. Java代码工具之中英文语句分词

    在自然语言处理中比较热门的操作就是中文或英文语句分词了,分词就是按照不同的算法和参数将语句分成若干词汇.拆分后的关键词可以进行词频统计或者词云图片生成等,能够快速方便的找到语句的核心主题热点. 在ja ...

  4. MATLAB基础操作之中英文切换

    这里写自定义目录标题 matlab实现界面中英文切换 中文修改成英文 英文修改成中文 matlab实现界面中英文切换 刚安装好matlab2022a,互相学习!需要安装包的可以留言,必回复. 中文修改 ...

  5. java国际化转换_java 实现国际化 中英文语言切换

    [实例简介] java实现国际化中英文语言切换 java语言切换JSP国际化 [实例截图] [核心代码] JAVA国际化实现 └── struts01 ├── src │   ├── com │   ...

  6. Java应用编程_常用类库汇总2(日期类正则表达式国际化程序)

    总览[Java SE] 相关文章链接 [Java应用编程_常用类库汇总1(字符串处理类&&对象克隆&数字操作类库&-)] [Java应用编程_常用类库汇总3(开发支持类 ...

  7. java编程思想 文献_JAVA编程思想英文参考文献和翻译

    JAVA编程思想英文参考文献和翻译 时间:2016-11-15 14:44来源:毕业论文 虽然java是基于C++基础上的,但是它更是纯粹的面向对象语 "If we spoke a diff ...

  8. Java简单编程题:大小写转换、兔子生兔子问题、狼追兔子问题、判断英文句子。

    Java简单编程题 1.大小写转换 2.兔子生兔子问题 3.狼追兔子问题 4.判断英文句子 1.大小写转换 输入一串字母 1.将大写转换为小写,小写转换为大写 2.将其全转换为小写 3.将其全转换为大 ...

  9. Java国际化教程_编程入门自学教程_菜鸟教程-免费教程分享

    教程简介 Java国际化入门教程 - 从简单的步骤了解Java国际化从基本到高级概念,包括概述,环境设置,区域设置,区域设置详细信息,显示语言,ResourceBundle,NumberFormat, ...

最新文章

  1. vo生成MySQL表_跟我学微服务统一开发平台-代码生成器
  2. linux 恢复数据
  3. 《调制解调算法》专栏导航贴
  4. python调用库函数用ecb模式加密图片_python 实现AES加密解密(ECB模式,配合base64)...
  5. Datawhale 零基础入门数据挖掘-Task3 特征工程
  6. CPU acceleration status:HAXM must be updated(version 1.1.16.0.1)
  7. HDU 4762 Cut the Cake
  8. C语言-学生管理系统
  9. 数字逻辑电路试题及答案
  10. 记录一次CenterOS7中xmrig挖矿病毒的排查测试
  11. c#设置导出Excel的列宽
  12. 2022-10-11 myql-exists子查询外表关联记录
  13. 怦然心动(Flipped)-7
  14. 台式计算机网卡驱动不能正常使用,系统提示“您的网卡驱动程序不正常!”怎么办 是什么原因...
  15. java 文件名排序_Java笔记:像win里一样文件名排序
  16. win系统下制作OS X(黑苹果)系统安装U盘制作的2个方法
  17. 应广单片机的RAM的清零方法
  18. Java高并发程序设计(三)——JDK并发包(二)
  19. 第二个MFC实例:GPA计算器
  20. Seurat | 强烈建议收藏的单细胞分析标准流程(差异分析与细胞注释)(五)

热门文章

  1. 山西阳泉中考计算机科目,2018阳泉中考科目及分值
  2. python应用:爬虫实例(静态网页)
  3. pyecharts x轴字体大小调整_PyEcharts实战指南
  4. sqlserver嵌套查询失败问题
  5. 律师事务所管理系统 v2.0
  6. URL编码/解码详解
  7. 嵌入式入门应该先学习STM32还是先学习51
  8. 赠与今年的大学毕业生-----------胡适
  9. 【Python】网络爬虫(静态网站)实例
  10. 在线词典助手安装教程