JTable内中文输入的一种解决方案
2009-09-30王占中,张涵
王占中,张涵
摘要:为了能在JTable表格中方便地输入中文数据,创造性地研究出某些特殊的能在中文输入法下直接启动数据输入的键盘键位。利用JAVA中机器人技术完成特定的动作,提高了用户输入的效率,也丰富了JAVA机器人技术的应用。
关键词:JAVA;JTable;机器人;事件监视器
中图分类号:TP312文献标示码:A文章编号:1009-3044(2009)34-9859-02
A Solution to Input Chinese Data in JTable
WANG Zhan-zhong, ZHANG Han
(Department of Computer Science and Information Engineering, Anyang Institute of Technology, Anyang 455000, China)
Abstract: In order to input conveniently Chinese Data in JTable, Some special keys of keyboard are found creatively, which can make sure users entering Chinese data without inputting anything. By JAVA Robot class, the program may execute automatically special tasks ,which improves users' work efficiency and expands the Robots application.
Key words: JAVA; JTable; robot; eventlistener
在用JAVA开发一个应用软件时,使用JTable作为输入界面接受用户输入的数据。用户在使用过程中发现:用英文输入法时非常方便,只要用制表键或方向箭头键移到要输入的表格位置,直接输入即可;而用中文输入法时,用上面的控制键移到要输入的位置时却无法直接输入数据,需要用户用鼠标点击相应位置一下才可以输入数据,给用户带来诸多不便。于是寻求解决的方法,愿将方法寻找的过程以及最后的结果奉献出来,供方家们指正。如有尺寸可取,不胜欣慰。
1 方案的寻求过程
初遇此问题,计划从JTable本身寻求解决方案。力图找到JTable对英文方式、中文方式的区别。经过研究JTable的文档资料,未能发现其对中英文方式的不同论述,这方面的努力未能成功。
既然在中文输入法下,每到一个表格,都需要而外加一个鼠标点击的动作,那么不妨由程序自动完成这一动作。这是解决这一问题最容易想到的方案,也是一种常规的方案。这一方案的问题是鼠标的位置确定需要较为复杂的计算。对不同的表,表格单元的位置是不一样的。既使同一表格显示形式的变化,也会影响表格单元的位置。当然JTable提供了从鼠标坐标到表格单元格位置的换算(rowAtPoint(Point p),columnAtPoint(Point p)),但没有提供相反的运算(确切地讲是没有提供直接的运算,其实可以运用JTable.getRowHeight(int row)和TableColumn.getWidth()计算)。所以计算特定的表格单元所含的点的坐标还是要费一些周折,尤其是各个行的高度、列的宽度可以各不相同。于是放弃了这一方面的努力。
在舍弃了前面两种方案之后,对中英文输入法进行了比较深入的研究与实践。力图找到在中英文输入法中表现完全一致的键位。也就是说,这些键位是不区分中文输入法和英文输入法的。换句话讲,这些键位是中文输入法中存在的少有的英文字符。输入这种键,虽在中文方式下,却可以直接启动输入过程,接着输入中文或英文都是可以的。实践证明在微软中文半角的情况下,如下几个键和英文输入法表现一致:BackSpace(回格)、Space(空格)、/(斜杠)、-(减号)、=(等号)。进一步考虑对输入内容的影响:这几个键中BackSpace(回格)键有可能使单元的内容减少一个字符,其余键都会使输入的内容有所增加。如使用Space(空格)真正的内容多一个空格,其它也一样。于是采取的方案是:先加一个Space(空格),然后加一个BackSpace(回格),内容不变,效果相当好。
2 涉及到的关键技术
实施本方案主要使用两种技术:事件监视器与机器人。
2.1 事件监视器技术
本来事件监视器技术是JAVA技术中通用的处理技术,没有论述的必要。但是将监视器放在什么位置还是值得斟酌的。程序的基本结构是这样的:在某JInternalFrame窗口内部放置两个JScrollPane面板,在其中一个面板内放置JTable组件。JInternalFrame窗口本身只是一个框架,在此放置监视器是不合适的,况且也没有添加监视器的方法,考虑到面板在此属于比较固定的组件,于是计划在JScrollPane面板上放置监视器。这里出现一个问题:在默认情况下,一个JScrollPane面板得不到键盘输入,即不能接受任何键盘事件。如想要使用必须要重载其isFocusTraversable方法,使其返回true[1]。这样比较繁琐。最后确定将监视器放置在JTable组件上。本来就是为JTable输入的问题,顺理成章。收到了预期的效果。
本文用到的监视器两种类型:键盘监视器和鼠标监视器。前者解决除首次输入的所有位置的输入问题,后者自然是解决首次输入问题。
2.2 AWT机器人技术
Robot类是自JAVA 2的1.3版本添加的,可以利用该类将击键和鼠标点击发送到任何AWT程序,该类一般用于自动用户界面的测试或演示程序[2]。将其用于对某一事件的反映,解决自动击键问题应该还是本论文的一个创新。
Robot类直接继承自Object类,它产生的事件不只是通知某事件队列或组件有某输入事件产生,而是引起真正的动作。也就是说它产生的鼠标事件、键盘事件能真正地模拟用户的击键和鼠标动作,从而实现某种自动化。本文就是利用机器人这一特点代替用户的重复击键和鼠标动作。
3 解决方案的实现
首先确定,表格单元输入数据时,可以改变单元格位置的键是Tab(制表)键、Enter(回车)键、上箭头、下箭头、左箭头、右箭头。于是设置键盘事件监视器,监视这几个键的动作。一旦用户点击这些键,由机器人完成既定操作。具体实现如下:
private class KeyHandler implements KeyListener{
public void keyPressed(KeyEvent event){
int keyCode=event.getKeyCode();
if(keyCode==KeyEvent.VK_TAB||keyCode==KeyEvent.VK_UP||keyCode==KeyEvent.VK_DOWN||keyCode==KeyEvent.VK_LEFT||keyCode==KeyEvent.VK_RIGHT||keyCode==KeyEvent.VK_ENTER){
robot.keyPress(KeyEvent.VK_SPACE);
robot.keyPress(KeyEvent.VK_BACK_SPACE);}}
public void keyReleased(KeyEvent event){}
public void keyTyped(KeyEvent event){}}
此键盘监视器实现了KeyListener接口。此接口有三个方法,在此用到keyPress方法,也就是击键方法来实现功能。对于用户击键的认定用到了虚拟键代码,虚拟键代码和PC机的扫描码类似(并且相关)。虚拟键代码的取值在KeyEvent类内定义[3],如Tab(制表)键的虚拟键代码为KeyEvent.VK_TAB,余者查阅相关的文档均有叙述,读者可从其取值推断出代表哪一个键。这样我们在输入数据时,击这些键时,输入焦距在移动到相应的单元格的同时,在用户输入数据之前自动击键,完成我们需要的动作。
到此,应该说大部分的目的已经实现,剩下的是精益求精的工作。解决初次输入数据时自动加入操作的问题。初次操作启于用户对相应表格单元的点击动作。于是再为JTable加入一个鼠标事件监视器,捕捉用户鼠标点击的操作。具体的监视器构造如下:
private class MouseHandler extends MouseAdapter{
public void mousePressed(MouseEvent e){
robot.keyPress(KeyEvent.VK_SPACE);
robot.keyPress(KeyEvent.VK_BACK_SPACE);}}
此鼠标监视器继承自MouseAdapter类。这里只是重载了mousePressed方法,利用这一方法完全能实现预定的功能。
4 讨论
在实际的软件开发工程中会遇到各种各样的问题,这需要开发人员认真分析具体的条件不拘一格地拿出解决方案。现阶段使用的大部分计算机软件来自西方国家特别是美国,默认的字符就是英文字符。中文字符的问题是一个远没有解决好的问题,值得关注。
本文就特定状态下遇到中文输入问题时的应对进行了一些介绍。关键之处:1) 对中英文两种输入法下表现完全相同的键位的探讨;2)对Robot类的应用领域的拓展。某个问题解决的方法可能有多个,作者提出的只是一种,希望能得到热心读者的指正。
参考文献:
[1] CayS. Horstmann Gary Cornell. Java 2核心技术卷I:原理(原书第5卷)[M]. 北京:机械工业出版社,2002.
[2] Sun. MicroSystems. Java SE6 Documentation. http://java.sun.com/javase/downloads/.
[3] Y. Daniel Liang. Java语言程序设计基础篇[M]. 北京:机械工业出版社,2006.