最近,项目上需要我们的一款java应用软件支持老挝语的输入,整体界面使用原来的英文即可。
本以为是个很简单的需求,因为java本身内部都是UNICODE编码,以为只要测试一下老挝语输入就行了,不需要改动代码。
结果,上机测试才发现,java的JTextField控件输入老挝语显示是乱码!如下图:
首先写了一个小程序测试,发现JTextField控件输入老挝语都是乱码,而AWT的TextField控件可以正常显示,于是排除java自身的问题,开始在控件本身查找问题。
查找资料发现,AWT控件的显示使用的是本地控件,而windows有一个很NB的uniscribe,可以在发现当前字体无法显示字符串时使用一种可用的默认字体显示。至于Swing控件,由于是自己实现的显示机制,所以没有这个功能,只能傻傻的按设定的字体显示,显示不出来就成了方块。
于是自己写了一个段代码,为JTextField扩展了自动适配字体的功能,如下:
JTextField testjTextField;//要扩展的JTextField控件
Font[] fList;
//初始化Font列表
String[] lstr = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
fList = new Font[lstr.length];
for(int i=0;i<lstr.length;i++)
{
fList[i]=new Font(lstr[i],testjTextField.getFont().getStyle(), testjTextField.getFont().getSize());
}
//监听输入的文本
testjTextField.addCaretListener(new MyTextListener());
private class MyTextListener implements CaretListener {
TextField tf = null;
String stxt = "";
@Override
public void caretUpdate(CaretEvent e) {
// TODO Auto-generated method stub
JTextField jtf = (JTextField)e.getSource();
String s = jtf.getText();
Font f = jtf.getFont();
if(f.canDisplayUpTo(s)!=-1)
{//发现不能显示字体,则查找可使用的字体
for(int i=0;i<fList.length;i++)
{
if(fList[i].canDisplayUpTo(s)==-1)
{
jtf.setFont(fList[i]);
break;
}
}
}
}
}
使用效果如下:
可以正常显示老挝语了。