在上一篇《打造專業外觀-九宮圖》,介紹了九宮格的概念并留下了一個演示程序。那個程序只是一個渲染過的窗口,許多必要的功能尚未實現,比如拖拽移動、改變大小、標題欄雙擊等。好現在就來一一實現。
你首先從這里下載上一篇程序的代碼,然后在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即可。
改進后的代碼這里下載