在上一篇《打造专业外观-九宫图》,介绍了九宫格的概念并留下了一个演示程序。那个程序只是一个渲染过的窗口,许多必要的功能尚未实现,比如拖拽移动、改变大小、标题栏双击等。好现在就来一一实现。
你首先从这里下载上一篇程序的代码,然后在eclipse中打开。
一、拖拽移动与双击标题栏。
为DemoShell类添加下列成员
private Point location;
注意:导入的时候仔细看import语句。import org.eclipse.swt.graphics.Point;而不是import java.awt.Point;
窗体的拖拽操作一般是拖拽窗体的标题栏,所以实现的思路就确定在northPanel了。方法就是为northPanel(充当标题栏)添加鼠标事件监听器。
northPanel.addMouseListener(this);
northPanel.addMouseMoveListener(this);
然后使DemoShell实现ControlListener、MouseListener、MouseMoveListener接口,并生成接口方法。
在mouseDoubleClick方法中添加如下代码:
if (e.getSource() == northPanel) {
setMaximized(!getMaximized());
}
首先判断如果双击是northPanel发起的,那么立即改变状态,只需一句话即可。
在mouseDown添加如下代码:
if (e.getSource() == northPanel) {
if (!getMaximized()) {
location = new Point(e.x, e.y);
}
}
同理,要判断是否是northPanel发出的双击事件。然后在窗口不是最大化时再为location赋值,注意,是在窗口不是最大化时,否则location就应该为null。之所以这么做是当窗体呈最大化状态时不应该移动,道理不难理解。
然后在mouseUp方法中添加如下代码:
if (e.getSource() == northPanel) {
location = null;
}
当鼠标抬起时,释放location。
接下来是最重要的mouseMove方法。该方法如下:
public void mouseMove(MouseEvent e) {
if (e.getSource() == northPanel) {
if (location != null) {
Point p = getDisplay().map(this, null, e.x, e.y);
setLocation(p.x - location.x, p.y - location.y);
}
}
}
注意:有对location不空的判断。map(Control from, Control to, int x, int y)函数是坐标转换,把from组件上的(x,y)坐标转换成to组件的坐标。null表示to组件就是桌面。如果你仔细研读《SWT自定义组件之Slider》就会比较容易理解。
现在你可以运行程序,发现窗口可以拖拽了。
二、改变大小
添加如下变量声名
private Point size;
然后在mouseDown方法中追加如下语句
else if (e.getSource() == southeastPanel) {
size = new Point(e.x, e.y);
}
在mouseUp中追加如下语句
else if (e.getSource() == southeastPanel) {
if (size == null) {
return;
}
setSize(new Point(getBounds().width + e.x - size.x,
getBounds().height + e.y - size.y));
size = null;
}
其原理同上。
这个时候可以改变尺寸了,再添加如下功能画龙点睛。
private Cursor seCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZESE);
private Cursor titleCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZEALL);
southeastPanel.setCursor(seCursor);
northPanel.setCursor(titleCursor);
好。现在运行程序观察下结果,但是美中不足的是,当拖拽右下角改变尺寸时,没有一个虚线来指示,能不能像前面《SWT自定义组件之Slider》虚拟划块那样实现呢,答案是不能,究其原因是Java支持的绘图操作还只能以组件为画布,不能实现在桌面上绘图,有待SWT、AWT(swing不行)在底层提供了这一功能。由于时间关系,只能先介绍移动、改变大小的实现。最小化、最大化、关闭等功能按钮,圆角,标题栏文字等的实现,以后再做介绍。不过您可以尝试标题栏文字着一功能,很简单,为northPanel添加addPaintListener即可。
改进后的代码这里下载