Java桌面技术

Java Desktop Technology

常用链接

统计

友情连接

最新评论

打造专业外观-三

在《打造专业外观-二》中,留下了3个未实现的功能:窗口标题和图标,边缘圆角,功能按钮。在本篇中将实现这些功能来完结打造专业外观-窗口部分的讲解。

一、窗口标题。
SWT窗口Shell有public void setText(String string),public void setImage(Image image) 方法用来设置标题和图标。但是现在窗口的样式已经是SWT.NO_TRIM,不再有标题栏了,因此标题只能自己“画”。在paintControl方法中添加如下代码:
else if (e.getSource() == northPanel) {
   String text = getText();
   if (text != null) {
    gc.setForeground(titleColor);
    gc.drawText(text, e.width / 2 - gc.stringExtent(text).x / 2,
      e.height / 2 - gc.stringExtent(text).y / 2, true);
   }
   Image image = getImage();
   if (text == null) {
    text = "";
   }
   if (image != null) {
    gc.drawImage(image, e.width / 2 - gc.stringExtent(text).x / 2
      - image.getBounds().width - 10, e.height / 2
      - image.getBounds().height / 2);
   }
  }
标题文字居中显示,图标居标题文字10像素。代码中“e.width”获取绘图环境上下文的长度,“gc.stringExtent(text).x”获得标题文字的长度,“true”表示绘制的文字不需要背景,如果是false,会看到有明显的灰色矩形作背景。绘制图标不难理解。当然通常的标题栏是九宫格的“上部”面板,所以要为northPanel添加绘制监听器。northPanel.addPaintListener(this);

二、边缘圆角
如果你不熟悉SWT的Region使用,请先研读http://www.eclipse.org/swt/snippets/中的“create a non-rectangular shell from a transparent image”程序。
该程序通过分析Image各个像素点的alpha值,来获取Region的填充。你可以通过本地图片实例化一个Image对象,支持透明的图片格式有PNG和GIF两种,美工都会知道这一点,本程序中用到的southwest.png、southeast.png、northeast.png、northwest.png均符合,以图片透明度来实现不规则窗体是常用的方法,这样做的好处是只要更换图片就可达到改变窗体形状。但是有些应用自身规定一种颜色为透明颜色,例如QQ,规定紫色为透明颜色,所以在它的实现中通过对图片逐个像素点分析,发现RGB是紫色就认为是透明。好,原理大致如此。下面来定义一个函数来完成次功能:
private Region getImageTransparenceRegion(Image image, int offsetX,
   int offsetY) {
  Region region = new Region();
  final ImageData imageData = image.getImageData();
  if (imageData.alphaData != null) {
   Rectangle pixel = new Rectangle(0, 0, 1, 1);
   for (int y = 0; y < imageData.height; y++) {
    for (int x = 0; x < imageData.width; x++) {
     if (imageData.getAlpha(x, y) != 255) {
      pixel.x = imageData.x + x + offsetX;
      pixel.y = imageData.y + y + offsetY;
      region.add(pixel);
     }
    }
   }
  }
  return region;
 }
该方法参考了Snippet21(http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet219.java?view=co),方法返回给定图片透明部分构造的Region。然后在controlResized末尾添加如下代码:
Region oldRegion = getRegion();
  if (oldRegion != null && !oldRegion.isDisposed()) {
   oldRegion.dispose();
  }
  Region newRegion = new Region();
  newRegion.add(0, 0, getSize().x, getSize().y);
  newRegion.subtract(getImageTransparenceRegion(northwestImage, 0, 0));
  newRegion.subtract(getImageTransparenceRegion(northeastImage,
    getSize().x - northeastImage.getBounds().width, 0));
  newRegion.subtract(getImageTransparenceRegion(southwestImage, 0,
    getSize().y - southwestImage.getBounds().y));
  newRegion.subtract(getImageTransparenceRegion(southeastImage,
    getSize().x - southeastImage.getBounds().width, getSize().y
      - southeastImage.getBounds().height));
  setRegion(newRegion);

Shell实例通过setRegion(Region region)设置区域来实现不规则巨型窗体,但是前提是把样式设置成SWT.NO_TRIM。
由于窗体尺寸的变更相应的区域也要跟着调整,所以要把逻辑写在controlResized方法中,而且每次改变过后要释放Region资源并重新设置新的区域。上述在初始化Region对象后,“newRegion.add(0, 0, getSize().x, getSize().y);”方法将覆盖窗口整个区域,随后的subtract挖掉四个角落的透明部分。

三、功能按钮
出于时间比较紧,只添加关闭按钮,其他按钮如最小化、最大化原理相同。
通常按钮有四种状态,分别是:正常态、鼠标在上方、鼠标按下、被禁用。这4态对应4个图标。由于时间关系,只对需要注意的地方简单介绍。具体见完整代码。
无疑,4种状态切换要添加鼠标事件监听器。关闭按钮通过声明private Composite closeButton;来实现。具体位置本程序实现是右端与northeastPanel相邻,左边与northPanel相邻。在鼠标抬起时,要检查抬起点是否在该按钮上,如果是才执行关闭操作。见如下代码
if (e.x > 0 && e.x < closeButton.getSize().x && e.y > 0
     && e.y < closeButton.getSize().y){
// 执行关闭操作,否则鼠标在关闭按钮上方按下,但是不在其上松开,表明用户放弃关闭行为。
}
重写dispose方法如下:
@Override
 public void dispose() {
  try {
   northwestImage.dispose();
   northeastImage.dispose();
   northImage.dispose();
   southwestImage.dispose();
   southeastImage.dispose();
   southImage.dispose();
   westImage.dispose();
   eastImage.dispose();
   closeImage.dispose();
   closeOverImage.dispose();
   color1.dispose();
   color2.dispose();
   titleColor.dispose();
  } finally {
   super.dispose();
  }
 }
首先是释放所有SWT本地资源,然后是super.dispose();释放窗口资源。

运行程序,界面效果如下


至此,打造专业外观-窗口部分的讲述就结束了,在这3篇幅中,主要讲述了九宫格的概念,九宫格法俗话说就是“贴图”,这个手法最常用也是最基础的,你会发现界面美观与否与图片有很大关系,同时桌面编程人员需要频繁与美工交互才能达到理想效果,如果没有合格的美工,但凭技术很难实现漂亮的外观,不过确实也存在只用多边形与曲线绘制组件的高手,swing的L&F就是这么实现的,但是贴图的好处是只要图片替换,外观也跟着替换,不用更改代码。

本程序只作为您设计的参考,欠缺还很多,并且没有对代码的健壮性、异常情况过多考虑,由于swt资源必须手工释放,如dispose方法中那样,其实那是最基本的,在实际环境下这么做还很有限,而且nullPoint异常也没有过多考虑。这都需要你自己去实现。

最终的完整程序这里下载

posted on 2007-11-07 00:49 sun_java_studio@yahoo.com.cn(电玩) 阅读(6441) 评论(6)  编辑  收藏 所属分类: NetBeansGUI Design

评论

# re: 打造专业外观-三[未登录] 2007-11-07 13:14 Thinker

受用  回复  更多评论   

# re: 打造专业外观-三 2007-11-07 19:06 William Chen

Hi 电玩,
文章写的不错,项目也做的非常漂亮。SWT都被你做成这个样子,佩服。
我对SWT并不太熟,稍有了解。其实对于swing,我也只是个人偏爱,至于SWT总有它适合的地方。我的文章的目的主要是纠正人们对于Swing的误解,希望人们不要对SWT过于迷信。所谓纠往必须过正嘛。
实际上没有正确与错误的技术,只有合适不合适的技术。
以前觉得国内都在搞Server Side Java,难得在这儿看到有这么多人对Java GUI感兴趣,而且技术都相当不错啊。
最近Java应用桌面开发逐渐升温,加上Sun对于桌面Java态度的改变,Java的开源,这些都必将促进Java桌面技术的复兴。
Java桌面技术前途还是比较光明的。  回复  更多评论   

# re: 打造专业外观-三[未登录] 2007-12-12 16:16 xiaoxiao

高手们,能不能加上最小化和最大化按钮。初学者  回复  更多评论   

# 打造专业外观-三 2008-05-22 15:51 swt

谢谢啊,收下了!!  回复  更多评论   

# re: 打造专业外观-三 2008-05-24 14:12 一啸长天

是啊....转做WEB也是一种无柰之举啊!  回复  更多评论   

# re: 打造专业外观-三 2008-05-24 15:19 sun_java_studio@yahoo.com.cn(电玩)

@一啸长天
Web是大趋势,但是不一定就是HTML,RIA的兴起将会带来一场革命,Flex、JavaFX和桌面程序开发很像。  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问  
 
TWaver中文社区