在上一篇《打造專業(yè)外觀-九宮圖》,介紹了九宮格的概念并留下了一個(gè)演示程序。那個(gè)程序只是一個(gè)渲染過(guò)的窗口,許多必要的功能尚未實(shí)現(xiàn),比如拖拽移動(dòng)、改變大小、標(biāo)題欄雙擊等。好現(xiàn)在就來(lái)一一實(shí)現(xiàn)。
你首先從這里下載上一篇程序的代碼,然后在eclipse中打開(kāi)。
一、拖拽移動(dòng)與雙擊標(biāo)題欄。
為DemoShell類添加下列成員
private Point location;
注意:導(dǎo)入的時(shí)候仔細(xì)看import語(yǔ)句。import org.eclipse.swt.graphics.Point;而不是import java.awt.Point;
窗體的拖拽操作一般是拖拽窗體的標(biāo)題欄,所以實(shí)現(xiàn)的思路就確定在northPanel了。方法就是為northPanel(充當(dāng)標(biāo)題欄)添加鼠標(biāo)事件監(jiān)聽(tīng)器。
northPanel.addMouseListener(this);
northPanel.addMouseMoveListener(this);
然后使DemoShell實(shí)現(xiàn)ControlListener、MouseListener、MouseMoveListener接口,并生成接口方法。
在mouseDoubleClick方法中添加如下代碼:
if (e.getSource() == northPanel) {
setMaximized(!getMaximized());
}
首先判斷如果雙擊是northPanel發(fā)起的,那么立即改變狀態(tài),只需一句話即可。
在mouseDown添加如下代碼:
if (e.getSource() == northPanel) {
if (!getMaximized()) {
location = new Point(e.x, e.y);
}
}
同理,要判斷是否是northPanel發(fā)出的雙擊事件。然后在窗口不是最大化時(shí)再為location賦值,注意,是在窗口不是最大化時(shí),否則location就應(yīng)該為null。之所以這么做是當(dāng)窗體呈最大化狀態(tài)時(shí)不應(yīng)該移動(dòng),道理不難理解。
然后在mouseUp方法中添加如下代碼:
if (e.getSource() == northPanel) {
location = null;
}
當(dāng)鼠標(biāo)抬起時(shí),釋放location。
接下來(lái)是最重要的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);
}
}
}
注意:有對(duì)location不空的判斷。map(Control from, Control to, int x, int y)函數(shù)是坐標(biāo)轉(zhuǎn)換,把from組件上的(x,y)坐標(biāo)轉(zhuǎn)換成to組件的坐標(biāo)。null表示to組件就是桌面。如果你仔細(xì)研讀《SWT自定義組件之Slider》就會(huì)比較容易理解。
現(xiàn)在你可以運(yùn)行程序,發(fā)現(xiàn)窗口可以拖拽了。
二、改變大小
添加如下變量聲名
private Point size;
然后在mouseDown方法中追加如下語(yǔ)句
else if (e.getSource() == southeastPanel) {
size = new Point(e.x, e.y);
}
在mouseUp中追加如下語(yǔ)句
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;
}
其原理同上。
這個(gè)時(shí)候可以改變尺寸了,再添加如下功能畫(huà)龍點(diǎn)睛。
private Cursor seCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZESE);
private Cursor titleCursor = new Cursor(getDisplay(), SWT.CURSOR_SIZEALL);
southeastPanel.setCursor(seCursor);
northPanel.setCursor(titleCursor);
好。現(xiàn)在運(yùn)行程序觀察下結(jié)果,但是美中不足的是,當(dāng)拖拽右下角改變尺寸時(shí),沒(méi)有一個(gè)虛線來(lái)指示,能不能像前面《SWT自定義組件之Slider》虛擬劃塊那樣實(shí)現(xiàn)呢,答案是不能,究其原因是Java支持的繪圖操作還只能以組件為畫(huà)布,不能實(shí)現(xiàn)在桌面上繪圖,有待SWT、AWT(swing不行)在底層提供了這一功能。由于時(shí)間關(guān)系,只能先介紹移動(dòng)、改變大小的實(shí)現(xiàn)。最小化、最大化、關(guān)閉等功能按鈕,圓角,標(biāo)題欄文字等的實(shí)現(xiàn),以后再做介紹。不過(guò)您可以嘗試標(biāo)題欄文字著一功能,很簡(jiǎn)單,為northPanel添加addPaintListener即可。
改進(jìn)后的代碼這里下載