java menuitem 乱码_MenuItem 顯示中文亂碼問題解決方案

今天在使用Java做系統托盤圖標(TrayIcon),需要為其增加一個右鍵彈出菜單(PopupMenu),在使用菜單項(MenuItem)時,遇到了一個非常痛苦的事情:中文亂碼~~~~。這個問題不經常碰到,但是一旦碰到就頭疼了,網上一搜,方法一大堆,但很少有方法能解決自己的問題,畢竟情況不一樣。

今天搞了一天,終於搞出了一套方案。

先說一下出問題的原因:

1. 本地系統區域語言字符集的問題,我們的系統可能默認的字符集為GB2312或GBK。

2. Java源文件編碼字符的問題,如果使用eclipse可以查看一下java source文件的編碼方式。

3. javac編譯時的字符問題,這一個問題很容易被忽略,運行一下javac可以看到有一個encoding的參數可以設置----這一個很重要。

4. 要讀取文件的編碼和讀取時的字符集設置問題,如果我們要用的字符串不是硬編碼在java源碼中,而是從資源文件中讀取時,就要注意這個問題了。

要解決問題需要做到如下:

1. 本地系統的語言字符可以不用管,主要看后面三項。

2. Java源文件的編碼,這一點很重要,最好使用utf8編碼。

我們在編輯文件時默認使用的是本地系統的字符集(如GBK),所以對Java源文件要進行字符轉換或提前做好設置,對於UE使用 文件--->轉換--->...到UTF-8(Unicode 編輯),對於eclipse設置  Window-->Preferences-->General-->Content Types--> Java Source File。具體操作此處不詳述。

3. javac編譯時的參數設置,增加encoding參數,如:javac -encoding utf8 Test.java

對於這一點要特別注意,eclipse的編譯器是沒有使用該參數的,我也沒找到該如何設置該參數(注意這里是編譯參數javac, 不是運行參數java或jvm, 不是run config中配置的),所以遇到這個問題的情況下不能使用eclipse來編譯了,至少在能配置javac之前是這樣。

不能使用eclipse了怎么辦呢,手工不是太可能,有幾種方案:

1. 手工編譯使用到MenuItem的類,目前只發現java.awt包會存在這個問題,swing包能很好的解決這種字符集變換的問題。

2. 使用其它編譯方式,如ant、Maven,它們都能配置javac。我現在就使用maven,只需要為它的編譯器加入encoding配置,如下:

Java代碼 2428aedc6cdbbbfa56cf6041e3e159f0.gif132b5b21b51f6f2f79671aca53b2ab78.png

ba6391f425d1ffd4f142fab8d273695a.gif

org.apache.maven.plugins

maven-compiler-plugin

2.3.2

1.6

1.6

utf8

....

org.apache.maven.plugins

maven-compiler-plugin

2.3.2

1.6

1.6

utf8

....

4. 要讀取的文件的字符編碼和讀取流編碼,對一個資源文件,我們也要設置其編碼為utf8(參照第2條,跟設置java源文件編碼是一樣的),同時在使用流讀取時也要設置流的讀取編碼(這個網上說java字符流的默認的是jvm的編碼,跟系統字符集一致)。

選說說我的場景吧,我要從一個文件中讀取字符串做為MenuItem的Label值(打算做國際化,呵呵),所以就需要對這個資源文件做處理,讀取流代碼如下:

Java代碼 2428aedc6cdbbbfa56cf6041e3e159f0.gif132b5b21b51f6f2f79671aca53b2ab78.png

ba6391f425d1ffd4f142fab8d273695a.gif

BufferedReader br =newBufferedReader(newInputStreamReader(newFileInputStream(langFile),"utf8"));

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(langFile), "utf8"));

這里還要注意的是:在復制這個資源文件時,最好也設置一下編碼,如用ant復制時:

Xml代碼 2428aedc6cdbbbfa56cf6041e3e159f0.gif132b5b21b51f6f2f79671aca53b2ab78.png

ba6391f425d1ffd4f142fab8d273695a.gif

tofile="D:\klaudisk-client\target\conf\settings.ini"overwrite="true"encoding="utf8"/>

tofile="D:\klaudisk-client\target\conf\settings.ini" overwrite="true" encoding="utf8"/>

好了,做到以上條件問題應該解決了。

在實際的過程中我們可以通過以下步驟一步一步來達到以上條件,每步都可以測試。

1. 查看源文件的編碼

這一點很簡單,對於eclipse查看一下java source file編碼方式就行了,保險一點就是修改一下編碼方式,會發現原來的java文件(含中文的)亂碼了,再改回來,就好了。 編碼方式請設置為utf8

2. 編譯編碼的測試

可以先寫一個小例子,使用硬編碼的方式加入中文,如MenuItem m = new MenuItem("中文"),你用eclipse運行后可以發現這個menu顯示的是亂碼(全是小方框)。然后你用命令行的方式編譯一下:javac -encoding utf8 Test.java。然后命令行運行,如果發現顯示正常了,則這及以前的測試通過了,如果還是亂碼,則需要你再次確認第1步。

3. 在前2部都確定成功的情況下再考慮讀取資源文件的測試,這個參照前面說的就行了。

--OK,問題應該能解決了,這種方式還可以應用到其它中文亂碼的問題上。

補充說明的是:awt不是不支持中文,是編碼轉換不夠智能。在swing中就解決了這些問題。

關於這個TrayIcon,我看oracle那邊已經提交了一個bug,意思是說要編寫一個對應的swing的JTrayIcon,從而使用JPopupMenu和JMenuItem。但這個bug不是因字符問題提交的。

對於MenuItem亂碼的問題,還可以使用JPopupMenu和JMenuItem來替代,參照如下,但情況不理想(彈出時必須要選擇一個菜單,否則不消失):

Java代碼 2428aedc6cdbbbfa56cf6041e3e159f0.gif132b5b21b51f6f2f79671aca53b2ab78.png

ba6391f425d1ffd4f142fab8d273695a.gif

ImageIcon icon =newImageIcon(UITest.class.getResource("16.gif"));

TrayIcon tray = newTrayIcon(icon.getImage());

tray.setImageAutoSize(true);

SystemTray.getSystemTray().add(tray);

tray.addMouseListener(newMouseAdapter() {

@Override

publicvoidmouseReleased(MouseEvent e) {

if(e.isPopupTrigger()) {

finalJPopupMenu pop =newJPopupMenu();

JMenuItem m1 = newJMenuItem("中文");

pop.add(m1);

pop.add(newJMenuItem("主題"));

pop.setLocation(e.getX(), e.getY());

pop.setInvoker(pop);

pop.setVisible(true);

}

}

});

ImageIcon icon = new ImageIcon(UITest.class.getResource("16.gif"));

TrayIcon tray = new TrayIcon(icon.getImage());

tray.setImageAutoSize(true);

SystemTray.getSystemTray().add(tray);

tray.addMouseListener(new MouseAdapter() {

@Override

public void mouseReleased(MouseEvent e) {

if (e.isPopupTrigger()) {

final JPopupMenu pop = new JPopupMenu();

JMenuItem m1 = new JMenuItem("中文");

pop.add(m1);

pop.add(new JMenuItem("主題"));

pop.setLocation(e.getX(), e.getY());

pop.setInvoker(pop);

pop.setVisible(true);

}

}

});

另外,對於第4點,資源文件的問題,還可以使用Properties.load()方法來加載.properties文件(該文件是被java bin下的navie2asc程序處理過的文件),這樣就不用管第4點問題了,但問題很顯然,不方便不直觀。

---EOF---

  • 0
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_39927378

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值