JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Java 程式分享區  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to postflat modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 [教學] i18n My experience
T55555

Java, Ruby, Haskell

版主

發文: 1026
積分: 24
於 2004-02-28 07:08 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
轉自己的貼...
(http://www.ownsky.org/cgi-bin/ut/topic_show.cgi?id=59705&h=1#585935)


Author: T55555
Subject: Java-i18n
Date: Nov. 2002


References:
* The Java Tutorial: Internationalization ( Sun Micro. )
http://java.sun.com/docs/books/tutorial/i18n/index.html

* Java internationalization basics ( IBM developerWorks )
http://www-105.ibm.com/developerworks/education.nsf/java-onlinecourse-bytitle/37415E1C6867D15A86256B9E004F2DAE?Open&t=egrL259,p=JavaUnicode

* Java Internationalization ( O’Reilly )
http://www.amazon.com/exec/obidos/tg/detail/-/0596000197/qid=1037631045/sr=1-5/ref=sr_1_5/102-4892991-5522561?v=glance&s=books

* Java I/O ( O’Reilly )
http://www.amazon.com/exec/obidos/tg/detail/-/1565924851/qid=1037630845/sr=1-1/ref=sr_1_1/102-4892991-5522561?v=glance&s=books

This article will not teach you how to do i18n.
Anything about local, format, resource bundle... etc. for i18n,
you could see the references to get more information.

This article is a note of how I resolve my small application about i18n problem,
more specific, is about how I show the Chinese character in my application.

In Window-XP English version, my application shows like diagram (A).
This is classic encoding problem; most time, I resolve this problem by using
NJStar software to convert and show me the Chinese character.

But this method does not work for Java Swing application:
First, Java String uses Unicode, can NJStar auto-convert Unicode String ?
Even NJStar can do that, there are a fatal problem, Java Swing is lightweight
components, tree and table are using "drawing" technique, which make
NJStar useless, because there are no OS native resource related,
so NJStar cannot catch the OS resource component and translate.
And when you ship your application, I think, you do not like assuming
your user always has NJStar.

So, this is the note about how I fix this problem, and hope this can also help
people who have the same problem as mine.

Step #1: Unicode conversion
For convert a local encoding data to Unicode data, you could do :
* Using "native2ascii.exe" tool.
* Using InputStreamReader. ( InputStreamReader( InputStream in, String charsetName ) )

But, In my case, I cannot use either those two methods, in fact,
my GB2312 code data is store in some database, via JDBC's getString
method, I got a Java Unicode String but the content is GB2312 data.
I do not like to research how to turning the JDBC driver to return correct Unicode String.
( it may-be possible for some Database. )

Now the problem is how to convert the String to correct Unicode String?
After look at String API, the simple way is:
1
String  corrrectString = new String( gb2312str.getBytes(), "GB2312" ) ;


Step #1B:
The Step #1 works, but it will create too many temporary objects.
Imagine if I have 60.000 string to convert, the step #1 will create
60.000 new string and 60.000 byte array objects.

The String.getBytes(int srcBegin, int srcEnd, byte[] dst, int dstBegin) is deprecated.
( I do not like use deprecated method to save 60.000 byte array creation )

I find out most of my data are ASCII, only data has character between 128 to 255 code
( 0x0080~0x00FF ) need to be convert. So, I create StringUtilities class to help convert:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import java.io.UnsupportedEncodingException;
 
/**
 * String utility class.
 * @author T55555
 */
public class StringUtilities {
 
    /** GB2312's Charset name. */ 
    public static final String GB2312_CHARSET_NAME = "GB2312";
    
    /** Big5's Charset name. */
    public static final String BIG5_CHARSET_NAME = "Big5"; 
 
    /** Help variable, set capacity by default to 256. */  
    private static char[] _chars = new char[256];
    
    /** "static class"; don't allow instantiated this class. */
    private StringUtilities() { }
    
    /**
     * If the input string contents LATIN_1_SUPPLEMENT character, 
     * then return the Unicode string correspond to the 
     * GB2312 input string; otherwise return the input string.
     * 
     * @param str String GB2312 to be converted.
     * @return String Unicode string correspond to <code>str</code>.
     */
    public static String convertGB2312(String str) {
        String s = str;
        int len = str.length();
        
        if (len > _chars.length) {
            _chars = new char[len];
        }
        
        str.getChars(0, len, _chars, 0);                       
        for (int i = 0; i < len; i++) {
            if ( Character.UnicodeBlock.of(_chars[ i ]) == 
                 Character.UnicodeBlock.LATIN_1_SUPPLEMENT ) {
                try {
                    s = new String(str.getBytes(), GB2312_CHARSET_NAME);
                } catch (UnsupportedEncodingException e) {
                    // just ignore, if the named encoding is not supported. 
                }
                break; 
            }
        }
        return s;
    }
    
}


This reuses the _char object, and creates new string only for the string need to be converted.
The LATIN_1_SUPPLEMENT represents char code 0x0080~0x00FF.
OK, After this step, my application looks like diagram ( B ).

Step #2: Swing, Font
After we have correct Unicode String, we need the
Unicode font to show those Chinese characters.
I found two Microsoft fonts can support Unicode :
"Arial Unicode MS.TFF" and "Arialuni.TTF"
If the font installed on the system, you could simply create the font by :
1
Font font = new Font ( "Arial Unicode MS", Font.PLAIN, 12 ) ;


If not, you could use Font.createFont ( int fontFormat, InputStream fontStream )
to create the font by using FileInputStream.

After that, just set the Swing components's font. That's it.

Step #2B:
Step #2 works perfectly, but if you have many swing components,
that may-be tedious to reset the font for all those swing components.
In my case, I need create customize TreeCellRender and TableCellRender
to set the Font. If most of components need use Unicode font,
the better way is make the Unicode font become default font. So I did :

1
2
3
    FontUIResource font = new FontUIResource ( "Arial Unicode MS", Font.PLAIN, 12 ) ;
    UIManager.put ( "Tree.font", font );
    UIManager.put ( "Table.font", font );


That help me to avoid create 2 customize renders!

OK, finally! Happy to see beautiful Chinese characters back again. ( diagram ( C ) )

Copyright by T55555, Nov. 2002

Diagrams:

(縮略圖,點擊圖片鏈接看原圖)


caterpillar edited on 2004-03-04 12:30
reply to postreply to post
話題樹型展開
人氣 標題 作者 字數 發文時間
7094 [教學] i18n My experience T55555 6615 2004-02-28 07:08
3994 Re:[分享] i18n My experience T55555 870 2004-02-28 07:11
» JWorld@TW »  Java 程式分享區

reply to postflat modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8