java程序美工加图_打造专业外观-三

在《打造专业外观-二》中,留下了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();释放窗口资源。

运行程序,界面效果如下

7cb756c9494b1c3386b1da853e768a3f.png

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

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

最终的完整程序这里下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值