The Goal
Keep walking…… |
當(dāng)一個(gè)GC方法在一個(gè)Drawabel對(duì)象上畫(huà)出一個(gè)圖案,它僅執(zhí)行這個(gè)painting過(guò)程一次。如果用戶(hù)改變對(duì)象尺寸或是用另一個(gè)窗口去覆蓋它,則圖形會(huì)被消除。因此,應(yīng)用程序能否在外界事件影響下維持其外觀這一點(diǎn)相當(dāng)重要。
這些外部事件被稱(chēng)為PaintEvents,接收它們的程序接口是PaintListener。一個(gè)Control在任何時(shí)候當(dāng)其外觀被應(yīng)用程序或是外界活動(dòng)改變都會(huì)觸發(fā)一個(gè)PaintEvent。這些類(lèi)對(duì)于事件和監(jiān)聽(tīng)器的使用方式都和我們?cè)诘谒恼聝?nèi)提到的類(lèi)似。由于PaintListener只有一個(gè)事件處理方法,所以不需要使用adapter類(lèi)
Canvas canvas = new Canvas(shell, SWT.NONE);
canvas.setSize(150, 150);
canvas.setLocation(20, 20);
canvas.addPaintListener(new PaintListener()
{
public void paintControl(PaintEvent pe)
{
GC gc = pe.gc;//每一個(gè)PaintEvent對(duì)象都包含有其自己的GC
gc.drawPolyline(new int[] {10,120,70,100,100,130,130,75});
}
});
shell.open();
每一個(gè)PaintEvent對(duì)象都包含有其自己的GC,主要有2個(gè)原因:1.因?yàn)檫@個(gè)GC instance是由事件產(chǎn)生的,所以PaintEvent會(huì)負(fù)責(zé)釋放他。2.應(yīng)用程序可以在shell open之前創(chuàng)建GC,這樣可以使圖形在一個(gè)獨(dú)立的類(lèi)中被創(chuàng)建。
SWT在PaintListener接口內(nèi)優(yōu)化painting過(guò)程,SWT的開(kāi)發(fā)者強(qiáng)烈建議Control的painting僅對(duì)PaintEvent作出反應(yīng)。如果一個(gè)應(yīng)用程序因?yàn)槠渌虮仨毟缕鋱D形,則他們推薦使用control的redraw()方法,這會(huì)在隊(duì)列中加入一個(gè)paint請(qǐng)求。之后,你可以調(diào)用update()方法來(lái)處理所有的綁定于該對(duì)象的paint請(qǐng)求。
需要牢記的是,雖然對(duì)于Control對(duì)象推薦在一個(gè)PaintListener內(nèi)painting,但是由于Device和Image對(duì)象并不能在該接口內(nèi)使用。如果你需要在一個(gè)image或device內(nèi)生成圖形,你必須單獨(dú)地生成一個(gè)GC對(duì)象并在使用結(jié)束后將其銷(xiāo)毀。
要客制化layout,需要繼承抽象類(lèi)Layout,需要寫(xiě)2個(gè)方法——computeSize() 和layout().
computeSize()
protected Point computeSize(Composite composite,
int wHint, int hHint,
boolean flushCache)
{
Point maxDimensions =
calculateMaxDimensions(composite.getChildren());
int stepsPerHemisphere =
stepsPerHemisphere(composite.getChildren().length);
int maxWidth = maxDimensions.x;
int maxHeight = maxDimensions.y;
int dimensionMultiplier = (stepsPerHemisphere + 1);
int controlWidth = maxWidth * dimensionMultiplier;
int controlHeight = maxHeight * dimensionMultiplier;
int diameter = Math.max(controlWidth, controlHeight);
Point preferredSize = new Point(diameter,
diameter);
... // code to handle case when our calculations
// are too large
return preferredSize;
}
參數(shù):
1.composite--The object we’re going to populate. At the time this method is called, it has children, but neither the composite nor the children have been sized or positioned on the screen.
2.wHint and hHint--layout所需的最大長(zhǎng)寬。若帶有參數(shù)SWT.DEFAULT,表示此layout可以隨意使用use whatever sizes it decides it needs.
3.flushCache--作為flag,to tell the layout whether it’s safe to use any cached values that it may be maintaining.
computeSize()的目的主要在于計(jì)算我們要layout的composite有多大
layout()
……
與之前所述的layout不同,form layout不是基于行和列的,它是基于與其他control之間的相對(duì)位置的。
FormLayout十分簡(jiǎn)單,你只要:1.設(shè)定頁(yè)邊距(高,寬)屬性。 2.設(shè)定spacing屬性,即所有control間的距離(in pixels)
同樣可以使用FormData來(lái)配置單個(gè)的control。
FormData
如果一個(gè)control沒(méi)有一個(gè)FormData實(shí)例來(lái)描述它的話,就會(huì)默認(rèn)放在composite的右上角
width和height屬性指定了control的尺寸,in pixels.
top, bottom, right, 和left屬性,每一個(gè)都有一個(gè)FormAttachment實(shí)例,這些attachments描述了control與其他control之間的關(guān)系。
FormAttachment
有2個(gè)使用途徑:
1.通過(guò)使用percentage of the parent composite.
2.通過(guò)設(shè)定一個(gè)control和另一個(gè)control之間的相對(duì)位置?
《圖》
package com.swtjface.Ch6;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.layout.*;
public class Ch6FormLayoutComposite extends Composite {
public Ch6FormLayoutComposite(Composite parent) {
super(parent, SWT.NONE);
FormLayout layout = new FormLayout();
setLayout(layout);
Text t = new Text(this, SWT.MULTI);
FormData data = new FormData();
data.top = new FormAttachment(0, 0);
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100);
data.bottom = new FormAttachment(75);//確定text的位置,因?yàn)樽笊辖鞘亲鴺?biāo)原點(diǎn),所以right的百分?jǐn)?shù)為100。
t.setLayoutData(data);
Button ok = new Button(this, SWT.NONE);
ok.setText("Ok");
Button cancel = new Button(this, SWT.NONE);
cancel.setText("Cancel");
data = new FormData();
data.top = new FormAttachment(t);
data.right = new FormAttachment(cancel);//ok按鈕在text下面,cancel左邊
ok.setLayoutData(data);
data = new FormData();
data.top = new FormAttachment(t);
data.right = new FormAttachment(100);//cancel按鈕在text下面,在最右邊
cancel.setLayoutData(data);
}
}
| |||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
26 | 27 | 28 | 29 | 30 | 31 | 1 | |||
2 | 3 | 4 | 5 | 6 | 7 | 8 | |||
9 | 10 | 11 | 12 | 13 | 14 | 15 | |||
16 | 17 | 18 | 19 | 20 | 21 | 22 | |||
23 | 24 | 25 | 26 | 27 | 28 | 29 | |||
30 | 1 | 2 | 3 | 4 | 5 | 6 |