日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

SWT 圖形繪畫接口詳解 (SWT Graphics)

 LibraryPKU 2013-11-25

摘要:

org.eclipse.swt.graphics包(package),包含了管理圖形資源的類。只要實(shí)現(xiàn)了org.eclipse.swt.graphics.Drawable接口,就可在上繪畫,包括 org.eclipse.swt.widgets.Controlorg.eclipse.swt.graphics.Imageorg.eclipse.swt.graphics.GC封裝了全部繪畫API,包括如何繪制線條、圖形、如何繪制文本、圖像以及填充圖形。 本篇展示如何使用GC在圖像上繪畫, 控件的繪畫事件(paintEvent回調(diào)。畫布(Canvas控件因?yàn)椴煌睦L畫操作,擁有很多構(gòu)造風(fēng)格常量允許你指定何時(shí)以及如何產(chǎn)生繪畫,本篇將展示這些東西。

英文原文:Graphics Context - Quick on the draw   http://www./articles/Article-SWT-graphics/SWT_graphics.html


目錄:

SWT圖形系統(tǒng)使用了與控件(Control)相同的坐標(biāo)習(xí)慣,即客戶區(qū)最左上角開始的點(diǎn)為原點(diǎn)(0,0),x軸坐標(biāo)向右增加,y軸坐標(biāo)向下增加。Point 類被用于描述位置(坐標(biāo)系統(tǒng)中的位置)以及偏移量(SWT中并沒有Dimension類,矩形(rectangle)的大小是由Point類捕獲的x、y坐標(biāo)點(diǎn)偏移量到原點(diǎn)坐標(biāo)來描述的)。

圖形上下文(Graphics Context)

圖形能夠被畫在任何實(shí)現(xiàn)了org.eclipse.swt.graphics.Drawable接口的東西上,比如控件(Control)、圖像(Image)、顯示設(shè)備或者打印設(shè)備。 org.eclipse.swt.graphics.GC 就是封裝了執(zhí)行繪畫操作的圖形上下文(graphics context)。一般有兩種使用GC的方法:一種是Drawable 實(shí)例作為GC構(gòu)造函數(shù)的參數(shù)獲取的GC,另一種是繪畫事件(paintEvent)回調(diào)提供的GC。

在圖像(Image)上繪畫

以下代碼是把一個(gè)圖像作為構(gòu)造參數(shù)獲取圖像的GC,然后在它上面繪制線條。 從左上角頂點(diǎn)(0,0)處右下角頂點(diǎn)畫線條  從右上角頂點(diǎn)向左下角頂點(diǎn)畫線條。

   

    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(); 

 原始圖像 繪制線條后的圖像

 

 由你創(chuàng)建的GC,就得由你負(fù)責(zé)銷毀它。調(diào)用 dispose()方法。關(guān)于怎樣管理 SWT 資源的更多信息請(qǐng)參見 SWT: The Standard Widget Toolkit 。一個(gè) GC 實(shí)例應(yīng)該在使用完后就盡可能快的釋放,這是因?yàn)槊恳粋€(gè)GC 都需要占用底層系統(tǒng)平臺(tái)資源,而在某些操作系統(tǒng)平臺(tái)中,這些資源是相當(dāng)匱乏的,例如Windows 98僅僅提供了5個(gè)GC 對(duì)象。

在控件(Control)上繪畫

org.eclipse.swt.widgets.Control實(shí)現(xiàn)了Drawable接口,所以你可以在控件(Control)上繪畫,圖像(Image)上繪畫方法與控件相同(把控件或圖像作為參數(shù)傳給GC獲取控件或圖像的GC,然后在其上進(jìn)行繪畫)。但是,圖像(Image)上繪畫與控件有所不同圖像的修改是永恒不變的。如果使用GC在控件上進(jìn)行繪畫,操作系統(tǒng)自身在繪制控件時(shí)會(huì)覆蓋你所做的繪畫操作。正確的方法的是為控件添加一個(gè)繪畫監(jiān)聽器,這個(gè)監(jiān)聽器類就是org.eclipse.swt.events.PaintListener,然后在監(jiān)聽器中回調(diào)方法參數(shù)就是org.eclipse.swt.events.PaintEvent的一個(gè)實(shí)例PaintEvent 包含了一GC,這樣在控件上面或者是指定區(qū)域里面進(jìn)行繪畫的環(huán)境就準(zhǔn)備好了

 

以下代碼 給Shell添加了一個(gè)繪畫監(jiān)聽, 然后在paintControl()方法中畫一條連接原點(diǎn)到底部右下角的直線。

    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的大小設(shè)置為(150,150), 但實(shí)際上可繪畫的區(qū)域比這還要再小一些,因?yàn)镾hell還包括了邊框、工具欄以及菜單欄這也就是我們所要了解的客戶區(qū)域。任何面板(Composite)都是使用getClientArea()方法獲取客戶區(qū)域的

因?yàn)閼?yīng)用程序總是在底層OS繪制完控件后才得到繪畫事件,所以繪畫事件中的GC進(jìn)行繪畫后的效果就可以最終顯示在控件上面了。當(dāng)然也有例外,比如工具欄區(qū)域就不能在上面進(jìn)行繪畫。org.eclipse.swt.widgets.Canvas 能夠用來進(jìn)行多方面的圖形繪畫操作。

 

剪切(Clipping)

一個(gè)GC的剪切區(qū)域就是發(fā)生繪畫的那部分,這里有個(gè)例子,如果你要填充出一個(gè)有缺口的三角形形狀,一種方法是畫出多個(gè)三角形和矩形組合出這么一個(gè)形狀;當(dāng)然也有另一種方法,就是利用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上畫了一個(gè)三角形。 左上角和右上角連接到底部邊緣的中間。使用一個(gè)矩形CG對(duì)其進(jìn)行剪切。 最后顯示出被剪切的矩形區(qū)域。 

 

 

當(dāng)控件發(fā)生繪畫事件,GC總是剪切需要重繪的那部分區(qū)域。例如,另一個(gè)窗口移到了一個(gè)SWT shell的前面,隨后又移走。那么需要重新顯示的就是GUI被損壞的那部分(shell被覆蓋的那部分),一個(gè)繪畫事件就是事件隊(duì)列。當(dāng)繪畫事件發(fā)生,paintControl(PaintEvent evt) 方法中的參數(shù)就包含了控件中需要的重繪區(qū)域的x、y坐標(biāo)字段及寬和高字段。控件的受損部分能夠包含若干個(gè)相分離的矩形區(qū)域,當(dāng)繪畫事件發(fā)生,控件的受損部 分不止一個(gè)時(shí),那么它們就會(huì)被合并成一個(gè)單一的矩形。這一步是由底層平臺(tái)來實(shí)現(xiàn)的,因?yàn)槎鄠€(gè)繪畫事件在單獨(dú)的一個(gè)回調(diào)過程中處理有利于執(zhí)行。

 

在上面的例子中每當(dāng) paintControl(PaintEvent)被調(diào)用的時(shí)候, 就將在PaintEvent's area中尋找一個(gè)優(yōu)化。繪畫事件(paint event)很可能不交叉在繪畫的形狀(shape)中,在這種情況下,就不需要繪畫(painting)或者指使需要一部分重畫而已。依靠繪畫的類型,就可以解決GC所選擇的繪畫部分,但事實(shí)上這要比GC剪切花費(fèi)更多開銷,而且在實(shí)踐中常常忽視這些被損壞的區(qū)域讓GC重新繪畫全部,只有在刷新操作中才會(huì)依賴剪切。

 

如果程序需要手工損壞控件的某部分區(qū)域,可以使用Control.redraw(int x, int y, int width, int height)或者使用Control.redraw()損壞整個(gè)客戶區(qū)域。此區(qū)域就被打上了標(biāo)記然后包含在下一個(gè)繪畫事件中,產(chǎn)生閃屏后,就會(huì)立即使用Control.update()方法強(qiáng)制處理控件的繪畫請(qǐng)求。如果無(wú)繪畫請(qǐng)求(也就是客戶區(qū)域無(wú)損壞), update()就什么不做。

(譯者注:此處的Control并不單指Control類,而是指所有繼承了Control類的控件類,比如button,canvas,shell等等)

畫布(Canvas)

雖然任何控件都可以通過繪畫事件(paintEvent)在其上進(jìn)行繪制, 但是org.eclipse.swt.widgets.Canvas 是針對(duì)圖形操作而特別設(shè)計(jì)的??梢灾苯邮褂肅anvas,也可以通過添加繪畫事件(paintEvent)使用,還可以創(chuàng)建Canvas的子類來自定義控件重復(fù)使用之。畫布(Canvas)擁有大量的風(fēng)格樣式來影響繪畫的產(chǎn)生。 

Canvas的默認(rèn)行為是使用當(dāng)前背景色填充自身的整個(gè)客戶區(qū)域。這樣會(huì)引起屏閃,因?yàn)槔L畫事件也是在GC上繪畫,所以用戶就會(huì)看到被填充的原始背 景色和產(chǎn)生繪畫之間的閃爍。有一種方法可避免此類情況,在創(chuàng)建Canvas時(shí)使用SWT.NO_BACKGROUND樣式。這樣就防止了繪畫背景,意思就 是程序要負(fù)責(zé)繪畫客戶區(qū)域的每一個(gè)像素。

 

當(dāng)部件調(diào)整大小時(shí),客戶區(qū)域會(huì)重復(fù)繪畫,這就會(huì)出現(xiàn)屏幕閃爍。使用SWT.NO_REDRAW_RESIZE 可減少這樣的情況,控件會(huì)減少不必要的重繪。比如改變尺寸大小,繪畫事件GC只會(huì)剪切需要重繪的部分即底部區(qū)域和右邊區(qū)域,就像一個(gè)反方向的“L”。

 

在固定大小的GC上繪畫NO-REDRAW_RESIZE樣式能很好的減少屏閃。但是錯(cuò)誤的使用NO_REDRAW_RESIZE 可以導(dǎo)致圖形成扁圓形。扁圓形是個(gè)大概的說法,事實(shí)上是指部件沒有隨大小的調(diào)整而進(jìn)行正確的更新。下面的例子就演示了這樣的情況。 填充橢圓形。因?yàn)樵诖翱诖笮「淖儠r(shí)沒有產(chǎn)生繪畫事件,因?yàn)镚C只剪切受損的(發(fā)生改變的)區(qū)域,而上一個(gè)繪畫又沒有被抹去,這就產(chǎn)生了扁圓形狀。( 即使用NO_REDRAW_RESIZE 繪畫事件只處理擴(kuò)大的那部分區(qū)域,原先部分它就不管了).

 

    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只剪切需要重繪的地方,扁圓形狀就產(chǎn)生了。

 

 

問題出在 ,應(yīng)該使用SWT.NONE 樣式,這樣GC就不會(huì)只剪切擴(kuò)大的部分了。所以當(dāng)Shell大小增大時(shí)整個(gè)橢圓形都會(huì)被重繪。

 

 final Canvas canvas = new Canvas(shell,SWT.NONE);

 

任何SWT部件,如果超過一個(gè)矩形區(qū)域被“損壞”,平臺(tái)會(huì)把它們合并成一個(gè),也就是說SWT程序只能處理一個(gè)繪畫事件。在Canvas上使用NO_MERGE_PAINTS 樣式可以覆蓋這樣的行為,可以為每一個(gè)被“損壞”的矩形區(qū)域調(diào)用繪畫事件監(jiān)聽。

 

風(fēng)格常量NO_BACKGROUND, NO_REDRAW_RESIZE 以及NO_MERGE_PAINTS 能夠被使用在任何面板(Composite)以及子類中, 包括Canvas、Shell以及Group。 雖然這是被SWT允許的(不會(huì)由異常拋出),但在Composite 類的Javadoc中關(guān)于風(fēng)格有這樣的警告 "... 如果在其他的Composite子類中(除了Canvas)使用其行為是不明確的。"。所以實(shí)現(xiàn)圖形繪畫操作Canvas應(yīng)該是首選。

 

另一種減少屏幕閃爍的方法,就是使用雙緩沖技術(shù)。你可以先根據(jù)Canvas客戶區(qū)域大小創(chuàng)建Image對(duì)象,然后使用GC(Image)將其繪畫到Canvas上;  在繪畫事件GC中調(diào)用drawImage(Image image, int x, int y)。 在一些平臺(tái)上已經(jīng)為你實(shí)現(xiàn)了雙緩沖,所以你可以根據(jù)情況考慮使用三緩沖。

 

繪制線條和形狀(Drawing lines and shapes) GC 擁有很多繪畫線條的方法,比如畫連接兩個(gè)坐標(biāo)點(diǎn)的直線、連接多個(gè)坐標(biāo)點(diǎn)的直線或者是預(yù)先定義好的形狀,線條顏色就是GC的前景色,可以通過風(fēng)格樣式常量來 決定線條的粗細(xì)胖瘦。繪畫事件其GC也有很多相同的屬性(前景色、背景色、以及顏色),并且線條的默認(rèn)寬度是1像素。

GC.drawLine(int x1, int y1, int x2, int y2);

畫一條從坐標(biāo)點(diǎn)(x1,y1)到坐標(biāo)點(diǎn)(x2,y2)的直線,如果兩點(diǎn)的坐標(biāo)值相同就相當(dāng)于畫一個(gè)圓點(diǎn)。

GC.drawPolyline(int[] pointArray);

畫一條連接多個(gè)坐標(biāo)點(diǎn)的直線,int[] 存放著要連接的x、y坐標(biāo)值。代碼如下:

gc.drawPolyline(new int[] { 25,5,45,45,5,45 });

先是從坐標(biāo)點(diǎn)25,5到45,45,然后從45,45到5,45。

 

GC.drawPolygon(int[] pointArray);

drawPolyline(int[])的使用與gc.drawPolyline很相似,不同的是最后一個(gè)點(diǎn)(5,45)連接了第一個(gè)點(diǎn)(25,5)。

gc.drawPolygon(new int[] { 25,5,45,45,5,45 });

相當(dāng)于用三條線段鏈接三角形的單個(gè)端點(diǎn),從而形成了一個(gè)三角形區(qū)域。

GC.drawRectangle(int x, int y, int width, int height);

畫一個(gè)矩形區(qū)域,int x,int y是矩形左上角的坐標(biāo)點(diǎn),int width,int heighy分別是矩形的寬和高。

gc.drawRectangle(5,5,90,45);

左上角坐標(biāo)點(diǎn)為(5,5),對(duì)角坐標(biāo)點(diǎn)為(95,50)。

你可以將Rectangle作為一個(gè)單獨(dú)的參數(shù)傳送給繪畫方法。GC.drawRectangle(Rectangle);

GC.drawRoundedRectangle(int x, int y, int width, int height, int arcWidth, int arcHeight);

圓角矩形不同于標(biāo)準(zhǔn)矩形,它的四角呈圓形。每一個(gè)圓角實(shí)際上就是一個(gè)1/4的橢圓形,其弧寬和弧高就是完整橢圓形的寬和高。

gc.drawRoundedRectangle(5,5,90,45,25,15)

畫了一個(gè)圓角矩形,左頂角坐標(biāo)值(5,5)。下面是圓角矩形的右下角放大圖,其寬和高分別是25、15。 

 

雖然調(diào)用4次drawArc()和4次drawLine()完全可以實(shí)現(xiàn)一個(gè)圓角矩形。但在一些平臺(tái)下,例如Windows或者Photon,SWT就可以使用非常優(yōu)秀的平臺(tái)API。

GC.drawOval(int x, int y, int width, int height);

一個(gè)橢圓形是畫在矩形里的,所以由矩形的左頂點(diǎn)坐標(biāo)以及寬和高來定義。定義一個(gè)正圓形同樣使用這個(gè)方法。

gc.drawOval(5,5,90,45);

GC.drawArc(int x, int y, int width, int height, int startAngle, int endAngle);

一個(gè)弧形是被畫在一個(gè)指明了高和寬以及左頂角x,y坐標(biāo)的矩形區(qū)域內(nèi)。int startAngle是個(gè)角度,是開始畫弧形的位置,開始點(diǎn)就是此角度與X軸坐標(biāo)線相交的那個(gè)點(diǎn)。int endAngle同樣是角度,它是弧形結(jié)束的位置,道理和int startAngle相同。

gc.drawArc(5,5,90,45,90,200);

這里畫了一個(gè)弧形,從90度垂線和X軸坐標(biāo)相交處開始,然后持續(xù)畫200度。

GC.setLineStyle(int style);

線條(Lines)擁有多種風(fēng)格,org.eclipse.swt.SWT中提供了定義線條風(fēng)格的常量,這些線條風(fēng)格常量以LINE_開頭。 
SWT.LINE_SOLID
SWT.LINE_DOT
SWT.LINE_DASH
SWT.LINE_DASHDOT
SWT.LINE_DASHDOTDOT

GC.setLineWidth(int width);

線條的默認(rèn)寬度是1像素(pixel), 當(dāng)然也可以使用GC的lineWidth字段設(shè)置線條寬。
gc.setLineWidth(2);
gc.setLineWidth(4);

因?yàn)榫€條風(fēng)格影響著所有的繪畫操作,所以這也就使你可以畫出不同邊線風(fēng)格的矩形或橢圓等圖形。

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);

 


當(dāng)GC的屬性被改變,比如像線條的寬度、線條的風(fēng)格或者是顏色,這些變化都會(huì)影響到后續(xù)的繪畫操作。以上代碼片段中,首先設(shè)置線條的寬度為3畫了一個(gè)橢圓,隨后重新設(shè)置線條屬性畫了一個(gè)邊線是虛線的矩形。在SWT圖形編程中,忘記重新設(shè)置這些字段屬性的值是經(jīng)常會(huì)犯的錯(cuò)誤。

繪制文本(Drawing text)

GC之上同樣可以繪制文本,文字的輪廓可通過GC的foreground color和font確定。你需要定義它的左上角坐標(biāo)(就是字體的位置)以及字體的高和寬。繪制文本有兩種設(shè)置方法:第一種是在drawText()繪制 方法里直接輸入文本它將處理行分隔符和tabs制表符,常用來模仿一個(gè)Label。第二種是在drawString()繪制方法中輸入字符串,沒有tab 以及回車處理,常用于更加復(fù)雜的控件,就像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 支持控制轉(zhuǎn)義字符,"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時(shí),tab 和回車換行轉(zhuǎn)義字符沒有被處理。在GC繪制時(shí)字符串所占的大小基于它的內(nèi)容和GC所設(shè)置的字體。獲取字符串所占寬度可以分別使用GC.stringExtent(String text)和GC.textExtent(String text)這兩個(gè)方法。 它們所返回的Point的x,y坐標(biāo)值分別就是寬和高。

GC.drawText(String text, int x, int y, boolean isTransparent);

drawText(String text, int x, int y)繪制的文本使用的是GC的當(dāng)前foreground color。當(dāng)你希望文本透過背景色在最頂層顯示的畫,你可設(shè)置它的isTransparent這個(gè)布爾型的參數(shù)為true。此方法在圖像(image) 上繪制時(shí)特別有用。

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);

 

 

 

填充矩形的時(shí)候,底部邊線和右邊線是不包含在內(nèi)的。雖然點(diǎn)(5,5)被包含在填充矩形的代碼中,但右下角點(diǎn) 95,50 (5+90 , 45+5) 不在填充區(qū)域的范圍里,右下角的填充點(diǎn)是94,49。這不同于drawRectangle(5,5,90,45),drawRectangle指的是整個(gè)形狀,所以其右下角點(diǎn)是95,50。

 

舉例說明一下,下面的代碼填充了一個(gè)矩形,但是填充的顏色并沒有覆蓋邊線。填充區(qū)域的右上角點(diǎn)坐標(biāo)以及寬和高都減小了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);

 

 

有點(diǎn)像 GC.fillRectangle(...)方法。底部邊框和右邊框都被排除在填充范圍之內(nèi),所以底部右下角坐標(biāo)變成了(94,49)而不是(9550)

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(...) 方法中的參數(shù)和drawArc(...)中的參數(shù)很相似。fillArc(...)遵守著和其他填充方法一樣的模式,底部邊框和右邊框不在填充范圍之內(nèi)。 

GC.fillGradientRectangle(int x, int y, int width. int height, vertical boolean);

對(duì)矩形進(jìn)行由前景色到背景色的漸變填充。Verticaltrue表示垂直漸變,反之則表示水平漸變。

gc.setBackgrouind(display,getSystemColor(SWT.COLOR_BLUE));
gc.fillGradientRectangle(5,5,90,45,false);

 

水平漸變從左邊的黑色前景色開始向右邊藍(lán)色背景色變化。正如其他的填充方法,底部和右邊框是被排除在外的,所以底部右下角會(huì)由1像素插入。 

 

gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
gc.setForeground(display.getSystemColor(SWT.COLOR_CYAN));
gc.fillGradientRectangle(5,5,90,45,true);

 

垂直漸變從上而下,由前景色向背景色變化。 

異或(XOR)

當(dāng)GC的繪畫發(fā)生時(shí)你可以在繪畫表面上編輯圖形的像素值,設(shè)置GC的異或(XOR)模式為true,每種顏色都是三原色紅、綠、藍(lán)經(jīng)過異或(XOR)操作后的結(jié)果,那么你就可以將幾種顏色經(jīng)過異或(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)矩形,當(dāng)在上面覆蓋一層藍(lán)色(0,0,255),或(XOR)后的顏色就是黃色(25,255,0)。白背景的部分和黃色異或后就成了黑色(0,0,0)。一個(gè)紅色背景的圓,它覆蓋在藍(lán)色上面異或(XOR)后就成了紫色(255,0,255)。蓋在白色上面異或(XOR)后就成了青色(0,255,255)。

 

(譯者注: SWT API幫助文檔中對(duì)setXORMode()方法是這樣描述的“此方法在某些平臺(tái)下是不被支持的,顯著表現(xiàn)的有Mac OS X,如果你希望你的代碼可運(yùn)行在所有平臺(tái),應(yīng)該盡量避免使用此方法?!保?/span>

繪制圖像(Drawing Images)

org.eclipse.swt.graphics.Image 表示一個(gè)已經(jīng)準(zhǔn)備好在顯示設(shè)備或打印設(shè)備上顯示的圖像。創(chuàng)建一個(gè)image對(duì)象最簡(jiǎn)單的方式就是從經(jīng)過驗(yàn)證的文件格式中加載文件。支持的文件格式有 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);

每一個(gè)圖像(image)都有一個(gè)由它自身范圍所決定的大小。例如圖像eclipse_lg.gif的大小就是115,164 ,可以使用image.getBounds()獲取。當(dāng)繪畫了一個(gè)圖像,此圖像就會(huì)以它自身范圍的寬度和高度顯示出來。

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);

根據(jù)原始圖像的寬度和高度,不但可以繪畫出不同大小的圖像還可以只繪畫原始圖像的局部。

src參數(shù)聯(lián)系圖像本身,要畫完整的圖像,srcX、srcY使用0,0,寬高就使用圖像的寬高。dst參數(shù)表示圖像被畫在哪里以及畫成多大。原始圖像的大小是115,164,若要把圖像寬度增加2倍,高度減低一半,可以使用下面的語(yǔ)句:

gc.drawImage(image,0,0,115,164,5,5,230,82);


 

 

使用src坐標(biāo)可以使你只畫出圖像的局部。例如,如果你只想畫出圖像的右上角部分,你可以設(shè)定src坐標(biāo)為20,0,寬度和高度為9582。下面的代碼中dst寬度和高度同樣使用95,82。通過指定不同大小就可以對(duì)圖像進(jìn)行拉長(zhǎng)或收縮操作。

gc.drawImage(image,20,0,95,82,5,5,95,82);

 

 

還能完成一些其他的圖像效果,比如圖像透明度、animation以及alpha通道。但這些不屬于本篇的討論范圍,我希望在以后的文章中能夠涉及到這些東西。

總結(jié)(Conclusion)

文已經(jīng)展示了如何使用GC畫線條、文本和填充形狀。給構(gòu)造器傳入一個(gè)drawable參數(shù)就能夠創(chuàng)建其GC,例如一個(gè)圖像、或者給控件(control使用繪畫事件(paintEvent)回調(diào)。 GC 的API允許設(shè)置前景色繪畫出線條并使用背景色填充。Canvas 控件允許通過繪畫事件paintEvent繪畫,并且當(dāng)繪畫事件發(fā)生時(shí)它有很多的構(gòu)造常量可以使用。GC 的剪切操作允許你控制只想顯示的部分,還有如何繪畫出不同風(fēng)格的線條以及顯示文本和圖像。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多