长久以来,Java被认为是服务器端的佼佼者,而在客户端方面不被看好,特别地MicroSoft的Windows系列几乎垄断了桌面应用。所以在大多数人看来只要一提起开发客户端,首先想到的是VB、Delph。拒绝Java的原因无非是速度慢、Swing外观丑陋这2点。对于前者已经成为历史了,而对于后者,抱怨Java设计的界面丑陋的那些人一定桌面开发经验浅显、或者只会依赖VB那种托拽生成组件的那些非高手。再有可能就是传统桌面开发员中的VB忠实fans,他们不愿意接受新东西。其实目前而言,Java开发桌面应用不仅能将上述缺点消除,Java最重要的是能够跨平台运行,这是其他语言不能达到的,如果客户端使用VB开发的话,那么还可能要考虑系统其他部分的开发是否也要用VB或者微软支持的产品。目前用Java语言开发的客户端已不少见,IBM Lotus旗下的Sametime系列就是很好的例子,虽然其7.5已经将界面全部改为SWT实现而不再是AWT,但至少能说明Java作为桌面开发绝不是弱者。而且调查显示Visual Basic开发用户直线下降。详见http://blog.sina.com.cn/s/blog_4b6047bc010006v9.html
对于一般界面需求而言,简单的桌面组件完全可以满足用户的需求,这些简单至极的组件已经被集成进组件托盘中了,如果你用netbeans或者安装Eclipse的VE插件,完全可以只通过托拽的方式将组件生成并放置在指定的地方。至多需要你对常用布局管理器有少许了解。但是单凭这些现有的玩意很难打造出专业的外观。比如一个顶层窗口,如果你用swing组件库中的JFrame或SWT中的Shell,那么它的外观充其量和本地的外观一致,这个本地化外观有窗口的标题栏,标题栏文字出现的位置,Windows是图标左对齐,Solaris是居中,和默认的最小化、最大化、关闭等按钮。另外还有固定尺寸和外观的边框,尽管在Windows Vista中这些元素已经很美观,但是某些软件如即时通讯类软件,美工一定会单独设计出一套截然不同的外观叫你去实现。就拿一个窗口来说,如下图:
我从事Java桌面相关的工作有1年半了,起初我依赖JButton、JScroll等基础组件,BorderLayout、FlowLayout等现成的布局管理器企图能实现类似MSN的外观效果,但是实际看来是完全不可能的,所以我当时就下了这样的结论,哪怕现在我依然认为是正确的:“抛弃所有的外观设计工具和一切现有的桌面组件及布局管理器,一切的一切必须自定义实现,设计工具最多能替你完成一半”。所以当时界面部分的代码是我一行一行写出来的,为了不做重复的劳动,定义了不少组件如Button,CheckBox,ComboBox(参见用SWT实现MSN风格的下拉框)、Slider(参见SWT自定义组件之Slider)。
布局管理器完全不用,因为它会给你的组件布局带来很大限制。取而代之的是为容器组件添加ComponentListener监听器(SWT的实现是ControlListener)。
下列是我基于这个理念开发的界面截图。
作为打造专业外观的第一步,应该学会如何去分解。介绍一种常见的分解方法——九宫格。如下图所示
九宫格的设计思想是将组件分成9个组成部分,四个边、四个角、中心部分作为内容放置其他组件。为了叙述方便,这9个部分依次取名为northwest(左上)、northeast(右上)、north(北)、southwest(左下)、southeast(右下)、south(南)、west(西)、east(东)、content(中心内容窗格)。
这9个部分的布局不难理解,例如northwest始终位于左上,无论窗口大小如何变动northwest都不会改变大小和位置;同理northeast始终位于右上位置;而north的左边紧贴northwest的右端、右边紧贴northeast的左边,所以north的长度计算应该是窗口的长度减去northwest和northeast的长度之和。同理,剩下几部分的布局不难计算。
还有一点是很重要的,如果你是用SWT组件,务必把Shell的样式设置成SWT.NO_TRIM,也就是说这样的顶层窗口没有标题栏和边框,一些由你来修饰。如果你用Swing,请使用JWindow而不是JFrame,道理同上。
虽然上述实现界面程序是用SWT编写的,但是不代表SWT很强大,Swing才是王者,你可以这样理解,SWT这样的怪胎都能做出如此效果,Swing更没问题了。
参考程序这里下载
本文只是介绍了九宫格的概念,在实际开发中可能需要对九宫格分解法进行扩展,比如在九宫格的基础上再分解,粒度由你来掌握。演示程序窗口只是简单地实现了边框和内容窗格的渲染,不能拖拽移动和改变尺寸、没有标题和功能按钮,如果你仔细看还会发现边角没有被抹去,也就是说被有实现圆角窗口,这些功能会在后续的文章中一一介绍如何实现。
至于上面所说UI代码一行一行写出来,是有些费事,对于这个问题我的看法是这样的:某些界面是不需要花大力气渲染的,比如说配置界面,没有哪些客户端要求那种界面也强调很酷的外观,所以对于简单的界面,可以借助工具生成代码,必定工具还是可以帮你做50%的事情。第二就积累一些组件库,比如自定义一些可重用组件,就像前面介绍的ComboBox和Slider,如果不能完全重用,至少可以将代码作为模板,少许改动就可变成另一套外观风格,研读前面介绍的ComboBox和Slider你会发现替换里面的图片或颜色常量就可轻松换肤,如果你的UI是基于swing的,那么你可以自定义L&F来实现基本的外观,关于L&F后面定会花大量时间整理出完整教程。第三就是利用配置的方式将UI组件的生成和布局从.java中移出来,这样不仅可以省去大部分代码量,而且配置文件简短易读的特点是众所周知的,Java Web项目的web.xml就是很好的例子,Spring就更不用说了。配置方式后面也会介绍。第四点,如果你只会VB、VC那种拖拽式开发,那你永远算不上高手,我曾经用MFC写程序时抱怨过“有那么多按钮却看不见一行CButton声明”,那会使你永远不了解底层是如何实现的,所以我不喜欢那种方式,如果你有能力,完全可以写一个Framework封装你的UI组件,配置生成的方式就是一例。
今后还会写大量关于Java GUI方面的帖子,并且会和Sun工程研究院的陈维雷先生合作发布L&F技术贴,他的博客https://blogs.oracle.com/Swing/想必大家很熟悉了。虽然当今的web2.0时代人们很少关注C/S应用,但是一些高端应用仍旧采用C/S模式,浏览器这个通用客户端能做的事还很有限。而且Sun也开始向桌面进军,JDK1.6的进步就能很好地说明这一点,更另人兴奋的是Java桌面技术有添加了一个新成员——JavaFX,又有好消息称JDK7.0中的AWT将加入不规则窗体和半透明窗体的支持,希望有一天Swing能垄断桌面。