新聞中心
目標(biāo)讀者必須熟悉Java開發(fā),并且有一定的Eclipse開發(fā)經(jīng)驗(yàn)。

十年建站經(jīng)驗(yàn), 成都網(wǎng)站建設(shè)、成都做網(wǎng)站客戶的見證與正確選擇。創(chuàng)新互聯(lián)公司提供完善的營(yíng)銷型網(wǎng)頁建站明細(xì)報(bào)價(jià)表。后期開發(fā)更加便捷高效,我們致力于追求更美、更快、更規(guī)范。
在 Eclipse網(wǎng)站上有一篇相關(guān)的文章"Creating Your Own Widgets using SWT",該文介紹了開發(fā)自己控件的很多基本概念、方法,并且通過實(shí)例進(jìn)行了介紹,非常好。但是其所用的實(shí)例比較簡(jiǎn)單,還有很多控件開發(fā)中所要涉及到的內(nèi)容,例如鍵盤、鼠標(biāo)事件的處理,滾動(dòng)條、焦點(diǎn)的處理等等沒有提及。本文通過開發(fā)一個(gè)自定義的顏色列表控件的實(shí)例,全面地介紹了自定義控件所涉及的技術(shù)。同時(shí),讀者也可以對(duì)該實(shí)例進(jìn)行擴(kuò)展,實(shí)現(xiàn)自己的列表控件。
SWT中提供的標(biāo)準(zhǔn)列表控件非常簡(jiǎn)單,只能提供字符串的選擇。我們經(jīng)常需要提供一些圖形列表供用戶選擇,這就需要自己開發(fā)自定義的列表控件。顏色選擇列表是我們常用的一種圖形列表,我們就以此為例進(jìn)行介紹。以下是我們將要開發(fā)的顏色列表。
我們?cè)陂_發(fā)自定義控件時(shí)主要考慮以下問題:
1、 自定義控件的繪制:通常我們需要自己對(duì)控件的形狀或圖案進(jìn)行繪制;
2、 控件對(duì)鍵盤事件的響應(yīng):當(dāng)焦點(diǎn)進(jìn)入控件,用戶進(jìn)行鍵盤操作,通過鍵盤對(duì)控件進(jìn)行控制時(shí),我們需要讓控件對(duì)用戶的操作進(jìn)行響應(yīng)。例如在列表中,用戶會(huì)通過上下箭頭改變列表的選擇項(xiàng);
3、 控件對(duì)鼠標(biāo)事件的響應(yīng):當(dāng)用戶用鼠標(biāo)選中控件,進(jìn)行操作時(shí),控件必須作出相應(yīng)的反應(yīng);
4、 控件對(duì)焦點(diǎn)事件的響應(yīng):當(dāng)界面焦點(diǎn)進(jìn)入或移出控件,通常我們需要將控件繪制成得到或失去焦點(diǎn)的形狀。例如,當(dāng)焦點(diǎn)進(jìn)入列表時(shí),一般被選中的列表項(xiàng)會(huì)有虛框表示選中。
5、 響應(yīng)TAB鍵:對(duì)于一個(gè)可操縱的控件,用戶可以用TAB鍵將焦點(diǎn)移入或移出。
6、 響應(yīng)滾動(dòng)條事件:當(dāng)控件有滾動(dòng)條時(shí),我們需要響應(yīng)用戶對(duì)滾動(dòng)條的操作,完成對(duì)控件的繪制工作。
7、 提供事件監(jiān)聽機(jī)制:程序員使用你的控件時(shí)通常需要監(jiān)聽控件中發(fā)生的一些事件,這樣當(dāng)事件發(fā)生時(shí),他們能夠進(jìn)行相應(yīng)處理。
8、 提供輔助功能(Accessibility):輔助功能是方便殘障人士使用時(shí)必須的,標(biāo)準(zhǔn)控件都會(huì)提供相應(yīng)的支持,我們自定義的控件也不例外。
9、 提供功能接口方便程序員訪問:通常為方便程序員使用時(shí)獲取控件中的信息或進(jìn)行設(shè)置,我們需要提供一些接口。
首先我們要開發(fā)的列表控件是一個(gè)基本控件,所以我們選擇Canvas作為我們開發(fā)的基類。
public class ColorList extends Canvas {
|
控件開發(fā)最重要的就是控件的繪制了。控件的繪制可以通過添加PaintListener,在它的paintControl方法中進(jìn)行。
addPaintListener(new PaintListener() {
|
這里要注意的是從PaintEvent中獲取的x,y,height,width是需要重繪的區(qū)域,x,y是以控件的左上角為原點(diǎn)的坐標(biāo)。在我們的程序中,為了性能起見,我們先根據(jù)需要重繪的區(qū)域計(jì)算出需要重繪的行數(shù),只重繪相應(yīng)的行,而不是將整個(gè)控件重繪。我們程序中用到的onPaint用于繪制一行。
接下來,我們要讓我們的控件響應(yīng)鍵盤上下鍵對(duì)列表項(xiàng)進(jìn)行選擇。我們已對(duì)向上鍵的處理為例,首先當(dāng)用戶按了向上鍵時(shí),我們需要改變選擇,并且重繪舊的和新的選擇項(xiàng)。如果選擇項(xiàng)已經(jīng)到了列表的頂部,我們還需要同時(shí)滾動(dòng)滾動(dòng)條。
addListener(SWT.KeyDown, new Listener() {
|
接下來,我們要讓我們的控件響應(yīng)鼠標(biāo)對(duì)列表項(xiàng)進(jìn)行選擇。首先我們要計(jì)算出鼠標(biāo)選中的行號(hào),注意MouseEvent中的y值只是相對(duì)于控件左上角的坐標(biāo),我們需要加上滾動(dòng)出了控件的部分。
addMouseListener(new MouseListener() {
|
當(dāng)我們的控件獲得焦點(diǎn)時(shí),選中的列表項(xiàng)需要有虛框表示控件得到焦點(diǎn)。當(dāng)獲得或失去焦點(diǎn)是,我們這里只需要簡(jiǎn)單的通知選中的項(xiàng)重畫。
addFocusListener(new FocusListener() {
|
我們?cè)诶L制每一個(gè)列表項(xiàng)時(shí)可以加入判斷當(dāng)前控件是否得到焦點(diǎn),如果控件得到了焦點(diǎn),我們就在選中的項(xiàng)目上畫一個(gè)虛框。下面是我們繪制一個(gè)列表項(xiàng)的代碼,注意在代碼的最后繪制焦點(diǎn)的虛框。
void onPaint(GC gc, int row, int beginx, int beginy, boolean isSelected) {
|
作為一個(gè)可操作的控件,TAB鍵的支持也是很重要的。由于我們的控件是從Canvas繼承過來的,不支持TAB鍵。下面的代碼使我們的控件有TAB鍵的支持:
addTraverseListener(new TraverseListener() {
|
很多時(shí)候,我們需要有滾動(dòng)條的支持。對(duì)于滾動(dòng)條,我們只要在上面加上selectionListener,處理它的widgetSelected事件就可以。
bar = getVerticalBar(); |
下面是函數(shù)scrollVertical的代碼。一旦用戶對(duì)滾動(dòng)條操作,我們就可以計(jì)算出要滾動(dòng)的區(qū)域,然后調(diào)用scroll函數(shù)。對(duì)函數(shù)scroll函數(shù)的調(diào)用會(huì)導(dǎo)致相應(yīng)區(qū)域的重繪。
| void scrollVertical(ScrollBar scrollBar) { Rectangle bounds = getClientArea(); int y = -scrollBar.getSelection(); if (y + maxY < bounds.height) { y = bounds.height - maxY; } if( y%lineHeight !=0 ) y = y - y % lineHeight - lineHeight; scroll(cx, y, cx, cy, maxX, maxY, false); cy = y; } |
現(xiàn)在我們的程序已經(jīng)基本成形了,我們來進(jìn)一步完善它。由于我們開發(fā)的控件是提供給程序員的,我們需要提供接口,讓外部知道控件中發(fā)生的事件。其中最重要的是列表項(xiàng)的選中事件。我們需要提供接口讓程序員能夠添加事件監(jiān)控器(listener)來監(jiān)控發(fā)生的事件,并且一旦發(fā)生事件,我們需要通知監(jiān)控器。
首先,我們添加一個(gè)成員來保存添加的事件監(jiān)控器:
Vector selectionListeners = new Vector(); |
我們?cè)僭黾右粋€(gè)函數(shù)addSelectionListener,讓程序員可以添加監(jiān)控器
| public void addSelectionListener(SelectionListener listener) { selectionListeners.addElement(listener); } |
在我們前面的代碼中,我們注意到每次選擇項(xiàng)改變,我們都會(huì)調(diào)用selectionChanged函數(shù)。下面是selectionChanged函數(shù)代碼。這里,我們會(huì)生成一個(gè) SelectionEvent事件,并且逐個(gè)調(diào)用事件監(jiān)控器的widgetSelected方法。這樣別人就可以監(jiān)聽到我們的事件了。
| public void selectionChanged() { Event event = new Event(); event.widget = this; SelectionEvent e = new SelectionEvent(event); for (int i = 0; i < selectionListeners.size(); i++) { SelectionListener listener = (SelectionListener) selectionListeners.elementAt(i); listener.widgetSelected(e); } } |
現(xiàn)在輔助功能(Accessibility)也日益成為軟件重要的部分,它是的殘疾人也能夠方便的使用我們的軟件。美國(guó)已經(jīng)立法,不符合Accessibility規(guī)范的軟件不能夠在政府部門銷售。我們開發(fā)的控件也需要支持Accessibility.下面的代碼使我們的控件有Accessibility支持。其中最重要的是getRole和getValue函數(shù)。我們的控件是從Canvas繼承,我們?cè)趃etRole函數(shù)中返回ACC.ROLE_LIST,這樣我們的控件才能讓屏幕閱讀軟件將我們的控件作為列表控件對(duì)待。
Accessible accessible = getAccessible(); |
最后,我們需要提供一些方法方便程序員使用我們的控件。
| public void setSelection(int index) { if (index >= getItemCount() || index < 0) return; oldRowSel = rowSel; rowSel = index; selectionChanged(); } public int getSelectionIndex() { return rowSel; } public int getItemHeight() { return lineHeight; } public void setItemHeight(int height) { lineHeight = height; } public int getItemCount() { return colors.size(); } public void add(int colorIndex, String colorName) { colorNames.add(colorName); colors.add(new Integer(colorIndex)); } |
我們開發(fā)的控件的使用也是非常簡(jiǎn)單的。
|
以上我們介紹了如何開發(fā)一個(gè)簡(jiǎn)單的自定義控件所需要涉及的技術(shù)。這里我們只以一個(gè)簡(jiǎn)單的顏色控件為例,但是一旦我們掌握了方法,我們很容易就可以開發(fā)出各種不同的漂亮控件。
整個(gè)程序完整的代碼清參考:ColorList.java。
【編輯推薦】
- Eclipse中perspective的兩種使用方法詳解
- 在Eclipse中使用JUnit4進(jìn)行單元測(cè)試(1)
- 在Eclipse中使用JUnit4進(jìn)行單元測(cè)試(2)
- 在Eclipse中使用JUnit4進(jìn)行單元測(cè)試(3)
- 奇怪的Eclipse debug異常
當(dāng)前名稱:開發(fā)Eclipse自定義控件
本文路徑:http://www.dlmjj.cn/article/cohieci.html


咨詢
建站咨詢
