java.awt.event.MouseEvent.isPopupTrigger()与跨平台的一点思考

今天遇到了Java下一个系统API类的问题,AWT下MouseEvent类的一个方法isPopupTrigger()让我困惑良久。

java.awt.event.MouseEvent.isPopupTrigger()这个方法是用来判断鼠标的点击是否构成触发弹出菜单的条件,通常情况下如果是由鼠标右键执行mousePressed()或mouseRelessed()的话isPopupTrigger()都会返回true。所以在我遇到的代码里面是这样写的:

在无论用鼠标左键还是右键按下并释放的时候都会触发这个匿名的MouseAdapter的mouseRelessed方法,但是只有当右键操作的时候isPopupTrigger()才返回true,弹出菜单才显示。

但是以上所说的都只是Windows下的情况,当我在Linux下运行这段代码的时候却发现无论怎样弹出菜单都不会显示,其原因就是在Linux下这里的isPopupTrigger()会永远返回false,Mac下测试的结果也一样。

一直以为跨平台的虚拟机应该不会出现这种不和谐的现象,然后按StackOverflow上的说明是在Linux和Mac OS X上isPopupTrigger()只会在mousePressed的情况下返回true,mouseRelessed则是false。

Oracel的文档如是说:

public boolean isPopupTrigger()
Returns whether or not this mouse event is the popup menu trigger event for the platform.
Note: Popup menus are triggered differently on different systems. Therefore, isPopupTrigger should be checked in both mousePressed and mouseReleased for proper cross-platform functionality.

按StackOverflow上的大神的解释,所谓的 “proper cross-platform functionality” 指的是不同操作系统下对于右键弹出菜单的不同设计。原来在早期的UNIX的X-Server桌面系统下约定俗成的右键弹出菜单的触发条件是按下右键就显示,这一传统设计一直延续到了如今的Ubuntu和Mac OS X上,而Windows下的设计却是按下右键再松开才弹出菜单(貌似Windows下所有的点按操作的设计都是按下再松开才触发)。而Java的这一设计意在照顾不同的操作系统用户的使用习惯。而要兼顾两种操作系统的原生设计推荐的做法就是把mousePressed()和mouseaRelessed()两个回调方法都重写一遍。

先不论这样的设计可能给开发者造成的麻烦,这的确刷新了我对跨平台的认识。以前我一直以为完美的跨平台就是可以在不同平台上用同样的程序,同样的操作方式和使用习惯,但看到Java的这个小细节我忽然感觉无比赞同,也许对于跨平台来说保持相同的操作方式和使用习惯并不重要,让用户可以保持不同平台原生的使用习惯才是最佳的。换言之,跨平台本质上是在跨不同的用户群。平台只是表象,用户才是根本,Java的跨平台思想的确了不起。

Leave a Reply

Your email address will not be published. Required fields are marked *