圖形上下文導論(Introduction to SWT Graphics)zz
圖形上下文導論(Introduction to SWT Graphics)
摘要:
org.eclipse.swt.graphics包(package),包含了管理圖形資源的類。只要實現了org.eclipse.swt.graphics.Drawable接口,就可在上面繪畫,包括 org.eclipse.swt.widgets.Control 和 org.eclipse.swt.graphics.Image 。 org.eclipse.swt.graphics.GC封裝了全部繪畫API,包括如何繪制線條、圖形、如何繪制文本、圖像以及填充圖形。 本篇將展示如何使用GC在圖像上繪畫, 控件的繪畫事件(paintEvent)回調。畫布(Canvas)控件,因為不同的繪畫操作,擁有很多構造風格常量允許你指定何時以及如何產生繪畫,本篇也將展示這些東西。
英文原文:Graphics Context - Quick on the draw http://www.eclipse.org/articles/Article-SWT-graphics/SWT_graphics.html
作者: Joe Winchester, IBM 2003年7月3日(July 3, 2003) 催月淚(Jaclick)翻譯 [email protected] 2007.5.30 Copyright 2003 International Business Machines Corp.目錄:
- 圖形上下文
- 在圖像(Image)上繪畫
- 在控件(control)上繪畫
- 切割(cliping)
- 畫布(Canvas)
- 繪制線條和形狀(Drawing lines and shapes)
- 繪制文本(Drawing text)
- 填充形狀(Filling shapes)
- 異或(XOR)
- 繪制圖像(Drawing images)
SWT圖形系統使用了與控件(Control)相同的坐標習慣,即客戶區最左上角開始的點為原點(0,0),x軸坐標向右增加,y軸坐標向下增加。Point 類被用於描述位置(坐標系統中的位置)以及偏移量(SWT中並沒有Dimension類,矩形(rectangle)的大小是由Point類捕獲的x、y坐標點偏移量到原點坐標來描述的)。
圖形上下文(Graphics Context)
圖形能夠被畫在任何實現了org.eclipse.swt.graphics.Drawable接口的東西上,比如控件(Control)、圖像(Image)、顯示設備或者打印設備。 org.eclipse.swt.graphics.GC 就是封裝了執行繪畫操作的圖形上下文(graphics context)。一般有兩種使用GC的方法:一種是讓Drawable 實例作為GC構造函數的參數獲取的GC,另外一種是繪畫事件(paintEvent)回調提供的GC。
在圖像(Image)上繪畫
以下代碼是把一個圖像作為構造參數獲取圖像的GC,然後在它上面繪制線條。 從左上角頂點(0,0)處向右下角頂點畫線條 從右上角頂點向左下角頂點畫線條。
Image image = new Image(display,"C:/devEclipse_02/eclipse/plugins/org.eclipse.platform_2.0.2/eclipse_lg.gif");
GC gc = new GC(image);
Rectangle bounds = image.getBounds();
gc.drawLine(0,0,bounds.width,bounds.height);
gc.drawLine(0,bounds.height,bounds.width,0);
gc.dispose();
image.dispose();
原始圖像 | 繪制線條後的圖像 |
由你創建的GC,就得由你負責銷毀它。調用 dispose()方法。關於怎樣管理 SWT 資源的更多信息請參見 SWT: The Standard Widget Toolkit 。一個 GC 實例應該在使用完後就盡可能快的釋放,這是因為每一個GC 都需要占用底層系統平臺資源,而在某些操作系統平臺中,這些資源是相當匱乏的,例如Windows 98僅僅提供了5個GC 對象。
在控件(Control)上繪畫
org.eclipse.swt.widgets.Control 實現了Drawable接口,所以你可以在控件(Control)上繪畫,圖像(Image)上繪畫方法與控件相同(把控件或圖像作為參數傳給GC獲取控件或圖像的GC,然後在其上進行繪畫)。但是,圖像(Image)上的繪畫與控件有所不同是圖像的修改是永恒不變的。如果使用GC在控件上進行繪畫,操作系統自身在繪制控件時會覆蓋你所做的繪畫操作。正確的方法的是為控件添加一個繪畫監聽器,這個監聽器類就是org.eclipse.swt.events.PaintListener,然後在監聽器中回調方法參數就是org.eclipse.swt.events.PaintEvent的一個實例。PaintEvent 包含了一GC,這樣在控件上面或者是指定區域裏面進行繪畫的環境就準備好了
以下代碼 給Shell添加了一個繪畫監聽, 然後在paintControl()方法中畫一條連接原點到底部右下角的直線。
Shell shell = new Shell(display);
shell.addPaintListener(new PaintListener(){
public void paintControl(PaintEvent e){
Rectangle clientArea = shell.getClientArea();
e.gc.drawLine(0,0,clientArea.width,clientArea.height);
}
});
shell.setSize(150,150)
雖然Shell的大小設置為(150,150), 但實際上可繪畫的區域比這還要再小一些,因為Shell還包括了邊框、工具欄以及菜單欄,這也就是我們所要了解的客戶區域。任何面板(Composite)都是使用getClientArea()方法獲取客戶區域的。
因為應用程序總是在底層OS繪制完控件後才得到繪畫事件,所以繪畫事件中的GC進行繪畫後的效果就可以最終顯示在控件上面了。當然也有例外,比如工具欄區域就不能在上面進行繪畫。org.eclipse.swt.widgets.Canvas
能夠用來進行多方面的圖形繪畫操作。
剪切(Clipping)
一個GC的剪切區域就是發生繪畫的那部分,這裏有個例子,如果你要填充出一個有缺口的三角形形狀,一種方法是畫出多個三角形和矩形組合出這麽一個形狀;當然也有另一種方法,就是利用GC的剪切操作。
shell.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
Rectangle clientArea = shell.getClientArea();
int width = clientArea.width;
int height = clientArea.height;
e.gc.setClipping(20,20,width - 40, height - 40);
e.gc.setBackground(display.getSystemColor(SWT.COLOR_CYAN));
e.gc.fillPolygon(new int[] {0,0,width,0,width/2,height});
}
});
這段代碼在Shell上畫了一個三角形。 左上角和右上角連接到底部邊緣的中間。使用一個矩形CG對其進行剪切。 最後顯示出被剪切的矩形區域。
當控件發生繪畫事件,GC總是剪切需要重繪的那部分區域。例如,另一個窗口移到了一個SWT shell的前面,隨後又移走。那麽需要重新顯示的就是GUI被損壞的那部分(shell被覆蓋的那部分),一個繪畫事件就是事件隊列。當繪畫事件發生,paintControl(PaintEvent evt)
方法中的參數就包含了控件中需要的重繪區域的x、y坐標字段及寬和高字段。控件的受損部分能夠包含若幹個相分離的矩形區域,當繪畫事件發生,控件的受損部分不止一個時,那麽它們就會被合並成一個單一的矩形。這一步是由底層平臺來實現的,因為多個繪畫事件在單獨的一個回調過程中處理有利於執行。
在上面的例子中每當 paintControl(PaintEvent)被調用的時候, 就將在PaintEvent‘s area中尋找一個優化。繪畫事件(paint event)很可能不交叉在繪畫的形狀(shape)中,在這種情況下,就不需要繪畫(painting)或者指使需要一部分重畫而已。依靠繪畫的類型,就可以解決GC所選擇的繪畫部分,但事實上這要比GC剪切花費更多開銷,而且在實踐中常常忽視這些被損壞的區域讓GC重新繪畫全部,只有在刷新操作中才會依賴剪切。
如果程序需要手工損壞控件的某部分區域,可以使用Control.redraw(int x, int y, int width, int height)或者使用
Control.redraw()
損壞整個客戶區域。此區域就被打上了標記然後包含在下一個繪畫事件中,產生閃屏後,就會立即使用Control.update()方法強制處理控件的繪畫請求。
如果無繪畫請求(也就是客戶區域無損壞), update()就什麽不做。
(譯者註:此處的Control並不單指Control類,而是指所有繼承了Control類的控件類,比如button,canvas,shell等等)
畫布(Canvas)
雖然任何控件都可以通過繪畫事件(paintEvent)在其上進行繪制, 但是org.eclipse.swt.widgets.Canvas
是針對圖形操作而特別設計的。可以直接使用Canvas,也可以通過添加繪畫事件(paintEvent)使用,還可以創建Canvas的子類來自定義控件重復使用之。畫布(Canvas)擁有大量的風格樣式來影響繪畫的產生。
Canvas的默認行為是使用當前背景色填充自身的整個客戶區域。這樣會引起屏閃,因為繪畫事件也是在GC上繪畫,所以用戶就會看到被填充的原始背景色和產生繪畫之間的閃爍。有一種方法可避免此類情況,在創建Canvas時使用SWT.NO_BACKGROUND樣式。這樣就防止了繪畫背景,意思就是程序要負責繪畫客戶區域的每一個像素。
當部件調整大小時,客戶區域會重復繪畫,這就會出現屏幕閃爍。使用SWT.NO_REDRAW_RESIZE 可減少這樣的情況,控件會減少不必要的重繪。比如改變尺寸大小,繪畫事件GC只會剪切需要重繪的部分即底部區域和右邊區域,就像一個反方向的“L”。
在固定大小的GC上繪畫NO-REDRAW_RESIZE樣式能很好的減少屏閃。但是錯誤的使用NO_REDRAW_RESIZE 可以導致圖形成扁圓形。扁圓形是個大概的說法,事實上是指部件沒有隨大小的調整而進行正確的更新。下面的例子就演示了這樣的情況。 填充橢圓形。因為在窗口大小改變時沒有產生繪畫事件,因為GC只剪切受損的(發生改變的)區域,而上一個繪畫又沒有被抹去,這就產生了扁圓形狀。( 即使用NO_REDRAW_RESIZE 繪畫事件只處理擴大的那部分區域,原先部分它就不管了).
shell.setLayout(new FillLayout());
final Canvas canvas = new Canvas(shell,SWT.NO_REDRAW_RESIZE);
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
Rectangle clientArea = canvas.getClientArea();
e.gc.setBackground(display.getSystemColor(SWT.COLOR_CYAN));
e.gc.fillOval(0,0,clientArea.width,clientArea.height);
}
});
canvas的大小被增大,GC只剪切需要重繪的地方,扁圓形狀就產生了。
問題出在 ,應該使用SWT.NONE 樣式,這樣GC就不會只剪切擴大的部分了。所以當Shell大小增大時整個橢圓形都會被重繪。
final Canvas canvas = new Canvas(shell,SWT.NONE);
任何SWT部件,如果超過一個矩形區域被“損壞”,平臺會把它們合並成一個,也就是說SWT程序只能處理一個繪畫事件。在Canvas上使用NO_MERGE_PAINTS 樣式可以覆蓋這樣的行為,可以為每一個被“損壞”的矩形區域調用繪畫事件監聽。
風格常量NO_BACKGROUND, NO_REDRAW_RESIZE 以及NO_MERGE_PAINTS 能夠被使用在任何面板(Composite)以及子類中, 包括Canvas、Shell以及Group。 雖然這是被SWT允許的(不會由異常拋出),但在Composite 類的Javadoc中關於風格有這樣的警告 "... 如果在其他的Composite子類中(除了Canvas)使用其行為是不明確的。
"。所以實現圖形繪畫操作Canvas應該是首選。
另一種減少屏幕閃爍的方法,就是使用雙緩沖技術。你可以先根據Canvas客戶區域大小創建Image對象,然後使用GC(Image)將其繪畫到Canvas上
; 在繪畫事件GC中調用drawImage(Image image, int x, int y)。
在一些平臺上已經為你實現了雙緩沖,所以你可以根據情況考慮使用三緩沖。
繪制線條和形狀(Drawing lines and shapes)
GC 擁有很多繪畫線條的方法,比如畫連接兩個坐標點的直線、連接多個坐標點的直線或者是預先定義好的形狀,線條顏色就是GC的前景色,可以通過風格樣式常量來決定線條的粗細胖瘦。繪畫事件其GC也有很多相同的屬性(前景色、背景色、以及顏色),並且線條的默認寬度是1像素。
GC.drawLine(int x1, int y1, int x2, int y2);
畫一條從坐標點(x1,y1)到坐標點(x2,y2)的直線,如果兩點的坐標值相同就相當於畫一個圓點。
GC.drawPolyline(int[] pointArray);
畫一條連接多個坐標點的直線,int[] 存放著要連接的x、y坐標值。代碼如下:
gc.drawPolyline(new int[] { 25,5,45,45,5,45 });
先是從坐標點25,5到45,45,然後從45,45到5,45。
GC.drawPolygon(int[] pointArray);
drawPolyline(int[])的使用與
gc.drawPolyline很相似,不同的是最後一個點(5,45)連接了第一個點(25,5)。
gc.drawPolygon(new int[] { 25,5,45,45,5,45 });
相當於用三條線段鏈接三角形的單個端點,從而形成了一個三角形區域。
GC.drawRectangle(int x, int y, int width, int height);
畫一個矩形區域,int x,int y是矩形左上角的坐標點,int width,int heighy分別是矩形的寬和高。
gc.drawRectangle(5,5,90,45);
左上角坐標點為(5,5),對角坐標點為(95,50)。
你可以將Rectangle作為一個單獨的參數傳送給繪畫方法。GC.drawRectangle(Rectangle);
GC.drawRoundedRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight);
圓角矩形不同於標準矩形,它的四角呈圓形。每一個圓角實際上就是一個1/4的橢圓形,其弧寬和弧高就是完整橢圓形的寬和高。
gc.drawRoundedRectangle(5,5,90,45,25,15)
畫了一個圓角矩形,左頂角坐標值(5,5)。下面是圓角矩形的右下角放大圖,其寬和高分別是25、15。
雖然調用4次drawArc()和4次drawLine()完全可以
實現一個圓角矩形。但在一些平臺下,例如Windows或者Photon,SWT就可以使用非常優秀的平臺API。
GC.drawOval(int x, int y, int width, int height);
一個橢圓形是畫在矩形裏的,所以由矩形的左頂點坐標以及寬和高來定義。定義一個正圓形同樣使用這個方法。
gc.drawOval(5,5,90,45);
GC.drawArc(int x, int y, int width, int height, int startAngle, int endAngle);
一個弧形是被畫在一個指明了高和寬以及左頂角x,y坐標的矩形區域內。int startAngle是個角度,是開始畫弧形的位置,開始點就是此角度與X軸坐標線相交的那個點。int endAngle同樣是角度,它是弧形結束的位置,道理和int startAngle相同。
gc.drawArc(5,5,90,45,90,200);
這裏畫了一個弧形,從90度垂線和X軸坐標相交處開始,然後持續畫200度。
GC.setLineStyle(int style);
線條(Lines)擁有多種風格,org.eclipse.swt.SWT中提供了定義線條風格的常量,這些線條風格常量以
LINE_開頭。
SWT.LINE_SOLID | |
SWT.LINE_DOT | |
SWT.LINE_DASH | |
SWT.LINE_DASHDOT | |
SWT.LINE_DASHDOTDOT |
GC.setLineWidth(int width);
線條的默認寬度是1像素(pixel), 當然也可以使用GC的lineWidth字段設置線條寬。
gc.setLineWidth(2); | |
gc.setLineWidth(4); |
因為線條風格影響著所有的繪畫操作,所以這也就使你可以畫出不同邊線風格的矩形或橢圓等圖形。
gc.setLineWidth(3);
gc.drawOval(5,5,40,40);
gc.setLineWidth(1);
gc.setLineStyle(SWT.LINE_DOT);
gc.setForeground(display.getSystemColor(SWT.COLOR_BLUE));
gc.drawRectangle(60,5,60,40);
當GC的屬性被改變,比如像線條的寬度、線條的風格或者是顏色,這些變化都會影響到後續的繪畫操作。以上代碼片段中,首先設置線條的寬度為3畫了一個橢圓,隨後重新設置線條屬性畫了一個邊線是虛線的矩形。在SWT圖形編程中,忘記重新設置這些字段屬性的值是經常會犯的錯誤。
繪制文本(Drawing text)
GC之上同樣可以繪制文本,文字的輪廓可通過GC的foreground color和font確定。你需要定義它的左上角坐標(就是字體的位置)以及字體的高和寬。繪制文本有兩種設置方法:第一種是在drawText()繪制方法裏直接輸入文本它將處理行分隔符和tabs制表符,常用來模仿一個Label。第二種是在drawString()繪制方法中輸入字符串,沒有tab以及回車處理,常用於更加復雜的控件,就像StyledText常用於
Eclipse Java editor那樣。
GC.drawText(String text, int x, int y);
Font font = new Font(display,"Arial",14,SWT.BOLD | SWT.ITALIC);
// ...
gc.drawText("Hello World",5,5);
gc.setForeground(display.getSystemColor(SWT.COLOR_BLUE));
gc.setFont(font);
gc.drawText("Hello\tThere\nWide\tWorld",5,25);
// ...
font.dispose();
drawText API 支持控制轉義字符,\t 就是tab,\n就是回車換行。
GC.drawString(String text, int x, int y);
Font font = new Font(display,"Arial",14,SWT.BOLD | SWT.ITALIC);
// ...
gc.drawString("Hello World",5,5);
gc.setForeground(display.getSystemColor(SWT.COLOR_BLUE));
gc.setFont(font);
gc.drawString("Hello\tThere\nWide\tWorld",5,25);
// ...
font.dispose()
使用drawString時,tab 和回車換行轉義字符沒有被處理。在GC繪制時字符串所占的大小基於它的內容和GC所設置的字體。獲取字符串所占寬度可以分別使用GC.stringExtent(String text)和
GC.textExtent(String text)這兩個方法。 它們所返回的Point的x,y坐標值分別就是寬和高。
GC.drawText(String text, int x, int y, boolean isTransparent);
drawText(String text, int x, int y)繪制的文本使用的是GC的當前foreground color。當你希望文本透過背景色在最頂層顯示的畫,你可設置它的isTransparent這個布爾型的參數為true。此方法在圖像(image)上繪制時特別有用。
Font font = new Font(display,"Arial",12,SWT.BOLD | SWT.ITALIC);
Image image = new Image(display,"C:/devEclipse_02/eclipse/plugins/org.eclipse.platform_2.0.2/eclipse_lg.gif");
GC gc = new GC(image);
gc.drawText("Hello World",5,5);
gc.setFont(font);
gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
gc.drawText("Hello World",5,25,true);
gc.dispose();
image.dispose();
font.dispose();
GC.drawText(String text, int x, int y, int flags);
int flags指的是SWT.DRAW_DELIMITER, SWT.DRAW_TAB, SWT.DRAW_TRANSPARENT 以及 SWT.DRAW_MNEMONIC 樣式常量。這些常量用來確定是否處理 \n , \t , 是否使用背景色透明,是否處理 &。
gc.drawImage(image,0,0);
gc.drawText("Hello\t&There\nWide\tWorld",5,5,SWT.DRAW_TRANSPARENT);
gc.drawText("Hello\t&There\nWide\tWorld",5,25,SWT.DRAW_DELIMITER | SWT.DRAW_TAB | SWT.DRAW_MNEMONIC );
填充形狀(Filling shapes)
使用GC的foreground color畫線條(邊線), 使用GC的background color填充形狀。
GC.fillPolygon(int[]);
gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
gc.fillPolygon(new int[] { 25,5,45,45,5,45 })
GC.fillRectangle(int x, int y, int width, int height);
gc.fillRectangle(5,5,90,45);
填充矩形的時候,底部邊線和右邊線是不包含在內的。雖然點(5,5)被包含在填充矩形的代碼中,但右下角點 95,50 (5+90 , 45+5) 不在填充區域的範圍裏,右下角的填充點是94,49。這不同於drawRectangle(5,5,90,45),drawRectangle指的是整個形狀,所以其右下角點是
95,50。
舉例說明一下,下面的代碼填充了一個矩形,但是填充的顏色並沒有覆蓋邊線。填充區域的右上角點坐標以及寬和高都減小了1像素。
gc.drawRectangle(5,5,90,45);
gc.setBackground(display.getSystemColor(SWT.COLOR_CYAN));
gc.fillRectangle(6,6,89,44);
GC.fillRoundedRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight);
gc.fillRoundRectangle(5,5,90,45,25,15);
有點像 GC.fillRectangle(...)方法。底部邊框和右邊框都被排除在填充範圍之內,所以底部右下角坐標變成了(94,49)而不是(95,50)
GC.fillOval(int x, int y, int width, int height);
gc.fillOval(5,5,90,45);
與其他的填充APIs相似
GC.fillArc(int x, int y, int widt4h., int height, int startAngle, int endAngle);
gc.fillArc(5,5,90,45,90,200);
fillArc(...)
方法中的參數和drawArc(...)中的參數很相似。fillArc(...)遵守著和其他填充方法一樣的模式,底部邊框和右邊框不在填充範圍之內。
GC.fillGradientRectangle(int x, int y, int width. int height, vertical boolean);
對矩形進行由前景色到背景色的漸變填充。Vertical為true表示垂直漸變,反之則表示水平漸變。
gc.setBackgrouind(display,getSystemColor(SWT.COLOR_BLUE));
gc.fillGradientRectangle(5,5,90,45,false);
水平漸變從左邊的黑色前景色開始向右邊藍色背景色變化。正如其他的填充方法,底部和右邊框是被排除在外的,所以底部右下角會由1像素插入。
gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
gc.setForeground(display.getSystemColor(SWT.COLOR_CYAN));
gc.fillGradientRectangle(5,5,90,45,true);
垂直漸變從上而下,由前景色向背景色變化。
異或(XOR)
當GC的繪畫發生時你可以在繪畫表面上編輯圖形的像素值,設置GC的異或(XOR)模式為true,每種顏色都是三原色紅、綠、藍經過異或(XOR)操作後的結果,那麽你就可以將幾種顏色經過異或(XOR)操作後得到新的顏色。
shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
// ...
gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
gc.fillRectangle(5,5,90,45);
gc.setXORMode(true);
gc.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
gc.fillRectangle(20,20,50,50);
gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
gc.fillOval(80,20,50,50);
被填充的背景色是白色的(255,255,255)矩形,當在上面覆蓋一層藍色(0,0,255),或(XOR)後的顏色就是黃色(25,255,0)。白背景的部分和黃色異或後就成了黑色(0,0,0)。一個紅色背景的圓,它覆蓋在藍色上面異或(XOR)後就成了紫色(255,0,255)。蓋在白色上面異或(XOR)後就成了青色(0,255,255)。
(譯者註: SWT API幫助文檔中對setXORMode()方法是這樣描述的“此方法在某些平臺下是不被支持的,顯著表現的有Mac OS X,如果你希望你的代碼可運行在所有平臺,應該盡量避免使用此方法。”)
繪制圖像(Drawing Images)
org.eclipse.swt.graphics.Image
表示一個已經準備好在顯示設備或打印設備上顯示的圖像。創建一個image對象最簡單的方式就是從經過驗證的文件格式中加載文件。支持的文件格式有 GIF, BMP (Windows 位圖), JPG, PNG, 新的Eclipse releases版還支持TIFF格式。
Image image = new Image(display,"C:/eclipse/eclipse/plugins/org.eclipse.platform_2.0.2/eclipse_lg.gif");
GC.drawImage(Image image, int x, int y);
每一個圖像(image)都有一個由它自身範圍所決定的大小。例如圖像eclipse_lg.gif的大小就是
115,164 ,可以使用image.getBounds()獲取。當繪畫了一個圖像,此圖像就會以它自身範圍的寬度和高度顯示出來。
gc.drawImage(image,5,5);
GC.drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight);
根據原始圖像的寬度和高度,不但可以繪畫出不同大小的圖像還可以只繪畫原始圖像的局部。
src 參數聯系圖像本身,要畫完整的圖像,srcX、srcY 使用0,0,寬高就使用圖像的寬高。dst 參數表示圖像被畫在哪裏以及畫成多大。原始圖像的大小是115,164,若要把圖像寬度增加2倍,高度減低一半,可以使用下面的語句:
gc.drawImage(image,0,0,115,164,5,5,230,82);
使用src坐標可以使你只畫出圖像的局部。例如,如果你只想畫出圖像的右上角部分,你可以設定src坐標為20,0,寬度和高度為95,82。下面的代碼中dst 寬度和高度同樣使用95,82。通過指定不同大小就可以對圖像進行拉長或收縮操作。
gc.drawImage(image,20,0,95,82,5,5,95,82);
還能完成一些其他的圖像效果,比如圖像透明度、animation以及alpha通道。但這些不屬於本篇的討論範圍,我希望在以後的文章中能夠涉及到這些東西。
總結(Conclusion)
本文已經展示了如何使用GC畫線條、文本和填充形狀。給構造器傳入一個drawable參數就能夠創建其GC,例如一個圖像、或者給控件(control)使用繪畫事件(paintEvent)回調。 GC 的API允許設置前景色繪畫出線條並使用背景色填充。Canvas 控件允許通過繪畫事件(paintEvent)繪畫,並且當繪畫事件發生時它有很多的構造常量可以使用。GC 的剪切操作允許你控制只想顯示的部分,還有如何繪畫出不同風格的線條以及顯示文本和圖像。
圖形上下文導論(Introduction to SWT Graphics)zz