graphic context是在GC類中的,GC對(duì)象是附著于現(xiàn)存的Controls。
要?jiǎng)?chuàng)建一個(gè)graphically oriented的應(yīng)用程序,首先要?jiǎng)?chuàng)建graphic context,并將其與一個(gè)component相關(guān)聯(lián),這兩步都可通過GC的constructor來(lái)實(shí)現(xiàn)。共有2個(gè)構(gòu)造函數(shù),見下:
1. GC(Drawable)--Creates a GC and configures it for the Drawable object
2. GC(Drawable, int)--Creates and configures a GC and sets the text-display style,第二個(gè)參數(shù)可以是RIGHT_TO_LEFT或LEFT_TO_RIGHT(默認(rèn)值);
第一個(gè)參數(shù)需要實(shí)現(xiàn)Drawable接口的對(duì)象, 此接口包含了與graphic context.內(nèi)部相聯(lián)系的方法。SWT提供了三個(gè)實(shí)現(xiàn)Drawable接口的類:Image, Device,?和 Control.

Control子類雖然都能包含圖形,但只有一個(gè)類是特別適合GC對(duì)象的:Canvas。它不僅提供了一個(gè)Composite的containment property,還可以用一系列的風(fēng)格來(lái)定義圖形在此區(qū)域內(nèi)如何顯示
示例:
package com.swtjface.Ch7;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
public class DrawExample
{
public static void main (String [] args)
{
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Drawing Example");
Canvas canvas = new Canvas(shell, SWT.NONE);
canvas.setSize(150, 150);
canvas.setLocation(20, 20);//在shell中創(chuàng)建canvas
shell.open ();
shell.setSize(200,220);
GC gc = new GC(canvas);//在canvas中創(chuàng)建graphic context
gc.drawRectangle(10, 10, 40, 45);
gc.drawOval(65, 10, 30, 35);
gc.drawLine(130, 10, 90, 80);
gc.drawPolygon(new int[] {20, 70, 45, 90, 70, 70});
gc.drawPolyline(new int[] {10,120,70,100,100,130,130,75});
gc.dispose();//釋放Color對(duì)象
while (!shell.isDisposed())
{
?if (!display.readAndDispatch())
?display.sleep();
?}
?display.dispose();
?}
?}
有兩點(diǎn)需要注意:1.在調(diào)用shell.open()之前構(gòu)建Canvas對(duì)象,然后在調(diào)用shell.open()之后創(chuàng)建和使用GC對(duì)象
???????????????????? 2.在使用完之后一定要立即釋放GC object
如上例所示GC提供了一系列在Drawable對(duì)象上畫圖形的方法,如下:

但是上例中有個(gè)問題:當(dāng)shell被變灰過或者最小化過之后,圖形就會(huì)被擦去。所以我們需要解決的事,無(wú)論window怎么變化,圖形都保持可見。因此SWT在一個(gè)Drawable對(duì)象被刷新后讓你自行控制。這個(gè)更新的過程就被稱為painting。
Painting and PaintEvents
當(dāng)一個(gè)GC方法在一個(gè)Drawabel對(duì)象上畫出一個(gè)圖案,它僅執(zhí)行這個(gè)painting過程一次。如果用戶改變對(duì)象尺寸或是用另一個(gè)窗口去覆蓋它,則圖形會(huì)被消除。因此,應(yīng)用程序能否在外界事件影響下維持其外觀這一點(diǎn)相當(dāng)重要。
這些外部事件被稱為PaintEvents,接收它們的程序接口是PaintListener。一個(gè)Control在任何時(shí)候當(dāng)其外觀被應(yīng)用程序或是外界活動(dòng)改變都會(huì)觸發(fā)一個(gè)PaintEvent。這些類對(duì)于事件和監(jiān)聽器的使用方式都和我們?cè)诘谒恼聝?nèi)提到的類似。由于PaintListener只有一個(gè)事件處理方法,所以不需要使用adapter類
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ú)立的類中被創(chuàng)建。
SWT在PaintListener接口內(nèi)優(yōu)化painting過程,SWT的開發(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é)束后將其銷毀。