开发Eclipse自定义控件
摘自:http://www.ibm.com/developerworks/cn/opensource/os-eclipcntl/
?
我們在開發(fā)自定義控件時主要考慮以下問題:
1、 自定義控件的繪制:通常我們需要自己對控件的形狀或圖案進(jìn)行繪制;
2、 控件對鍵盤事件的響應(yīng):當(dāng)焦點(diǎn)進(jìn)入控件,用戶進(jìn)行鍵盤操作,通過鍵盤對控件進(jìn)行控制時,我們需要讓控件對用戶的操作進(jìn)行響應(yīng)。例如在列表中,用戶會通過上下箭頭改變列表的選擇項;
3、 控件對鼠標(biāo)事件的響應(yīng):當(dāng)用戶用鼠標(biāo)選中控件,進(jìn)行操作時,控件必須作出相應(yīng)的反應(yīng);
4、 控件對焦點(diǎn)事件的響應(yīng):當(dāng)界面焦點(diǎn)進(jìn)入或移出控件,通常我們需要將控件繪制成得到或失去焦點(diǎn)的形狀。例如,當(dāng)焦點(diǎn)進(jìn)入列表時,一般被選中的列表項會有虛框表示選中。
5、 響應(yīng)TAB鍵:對于一個可操縱的控件,用戶可以用TAB鍵將焦點(diǎn)移入或移出。
6、 響應(yīng)滾動條事件:當(dāng)控件有滾動條時,我們需要響應(yīng)用戶對滾動條的操作,完成對控件的繪制工作。
7、 提供事件監(jiān)聽機(jī)制:程序員使用你的控件時通常需要監(jiān)聽控件中發(fā)生的一些事件,這樣當(dāng)事件發(fā)生時,他們能夠進(jìn)行相應(yīng)處理。
8、 提供輔助功能(Accessibility):輔助功能是方便殘障人士使用時必須的,標(biāo)準(zhǔn)控件都會提供相應(yīng)的支持,我們自定義的控件也不例外。
9、 提供功能接口方便程序員訪問:通常為方便程序員使用時獲取控件中的信息或進(jìn)行設(shè)置,我們需要提供一些接口。
首先我們要開發(fā)的列表控件是一個基本控件,所以我們選擇Canvas作為我們開發(fā)的基類。
?
public class ColorList extends Canvas {Vector colors = new Vector(); // 用于保存我們顏色控件中的顏色值Vector colorNames = new Vector(); // 用于保存顏色控件中的顏色名字int rowSel = -1; // 用于保存當(dāng)前選中的行號int oldRowSel = -1; // 用于保存上一次選中的行號int maxX, maxY; // 用于保存列表的寬度和高度int lineHeight; // 用于設(shè)置行高int cx = 0; // 滾動條滾動后,控件的圖形相對于控件可見區(qū)域左上角的x坐標(biāo)int cy = 0; // 滾動條滾動后,控件的圖形相對于控件可見區(qū)域左上角的y坐標(biāo)}
控件開發(fā)最重要的就是控件的繪制了。控件的繪制可以通過添加PaintListener,在它的paintControl方法中進(jìn)行。
addPaintListener(new PaintListener() {public void paintControl(PaintEvent e) {GC gc = e.gc;Point size = getSize();int beginx = e.x;int beginy = (e.y / lineHeight) * lineHeight;int beginLine = (e.y - cy) / lineHeight;int endLine = beginLine + e.height / lineHeight + 1;if (endLine > getItemCount())endLine = getItemCount();for (int i = beginLine; i < endLine; i++) {boolean selected = false;if (i == rowSel)selected = true;onPaint(gc, i, cx, beginy + (i - beginLine) * lineHeight,selected);}}});
這里要注意的是從PaintEvent中獲取的x,y,height,width是需要重繪的區(qū)域,x,y是以控件的左上角為原點(diǎn)的坐標(biāo)。在我們的程序中,為了性能起見,我們先根據(jù)需要重繪的區(qū)域計算出需要重繪的行數(shù),只重繪相應(yīng)的行,而不是將整個控件重繪。我們程序中用到的onPaint用于繪制一行。
接下來,我們要讓我們的控件響應(yīng)鍵盤上下鍵對列表項進(jìn)行選擇。我們已對向上鍵的處理為例,首先當(dāng)用戶按了向上鍵時,我們需要改變選擇,并且重繪舊的和新的選擇項。如果選擇項已經(jīng)到了列表的頂部,我們還需要同時滾動滾動條。
?
addListener(SWT.KeyDown, new Listener() {public void handleEvent(Event event) {switch (event.keyCode) {case SWT.ARROW_UP: // 處理向上鍵if (rowSel != 0) {oldRowSel = rowSel;rowSel--;if (oldRowSel != rowSel) { //發(fā)送消息讓控件重繪((Canvas) event.widget).redraw(cx, (rowSel + cy/ lineHeight)* lineHeight, maxX, lineHeight*2, false);}if (rowSel < -cy / lineHeight) { //如果需要,滾動滾動條ScrollBar bar = ((Canvas) event.widget).getVerticalBar();bar.setSelection(bar.getSelection() - lineHeight);scrollVertical(bar);}selectionChanged(); // 發(fā)送selectionChanged事件}break;case SWT.ARROW_DOWN: // down arror key…break;}}});
接下來,我們要讓我們的控件響應(yīng)鼠標(biāo)對列表項進(jìn)行選擇。首先我們要計算出鼠標(biāo)選中的行號,注意MouseEvent中的y值只是相對于控件左上角的坐標(biāo),我們需要加上滾動出了控件的部分。
addMouseListener(new MouseListener() {public void mouseDoubleClick(MouseEvent e) {}public void mouseDown(MouseEvent e) {int row = (e.y - cy) / lineHeight; //計算選中的行if (row >= 0) {oldRowSel = rowSel;rowSel = row;}if (oldRowSel != rowSel) { // 重畫舊的和新的選擇項((Canvas) e.getSource()).redraw(cx, (e.y / lineHeight)* lineHeight, maxX, lineHeight, false);((Canvas) e.getSource()).redraw(cx, (oldRowSel + cy/ lineHeight)* lineHeight, maxX, lineHeight, false);}selectionChanged();}public void mouseUp(MouseEvent e) {}}); 當(dāng)我們的控件獲得焦點(diǎn)時,選中的列表項需要有虛框表示控件得到焦點(diǎn)。當(dāng)獲得或失去焦點(diǎn)是,我們這里只需要簡單的通知選中的項重畫。
addFocusListener(new FocusListener() {public void focusGained(FocusEvent e) {((Canvas) e.getSource()).redraw(cx, rowSel * lineHeight, maxX,lineHeight, true);}public void focusLost(FocusEvent e) {((Canvas) e.getSource()).redraw(cx, rowSel * lineHeight, maxX,lineHeight, true);}});
我們在繪制每一個列表項時可以加入判斷當(dāng)前控件是否得到焦點(diǎn),如果控件得到了焦點(diǎn),我們就在選中的項目上畫一個虛框。下面是我們繪制一個列表項的代碼,注意在代碼的最后繪制焦點(diǎn)的虛框。
?
void onPaint(GC gc, int row, int beginx, int beginy, boolean isSelected) {Color initColor = gc.getBackground();Color initForeColor = gc.getForeground();if (isSelected) {gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION));gc.fillRectangle(beginx, beginy, maxX, lineHeight);gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));} else {gc.setBackground(initColor);}gc.drawString((String) colorNames.get(row), beginx + 24, beginy);Color color = Display.getCurrent().getSystemColor(((Integer) colors.get(row)).intValue());gc.setBackground(color);gc.fillRectangle(beginx + 2, beginy + 2, 20, lineHeight - 4);gc.setBackground(initColor);gc.setForeground(initForeColor);if (isFocusControl() && isSelected)gc.drawFocus(cx, beginy, maxX, lineHeight);}
作為一個可操作的控件,TAB鍵的支持也是很重要的。由于我們的控件是從Canvas繼承過來的,不支持TAB鍵。下面的代碼使我們的控件有TAB鍵的支持:
addTraverseListener(new TraverseListener() {public void keyTraversed(TraverseEvent e) {if (e.detail == SWT.TRAVERSE_TAB_NEXT|| e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {e.doit = true;}};});
很多時候,我們需要有滾動條的支持。對于滾動條,我們只要在上面加上selectionListener,處理它的widgetSelected事件就可以。
bar = getVerticalBar();if (bar != null) {bar.addSelectionListener(new SelectionAdapter() {public void widgetSelected(SelectionEvent event) {scrollVertical((ScrollBar) event.widget);}});}
下面是函數(shù)scrollVertical的代碼。一旦用戶對滾動條操作,我們就可以計算出要滾動的區(qū)域,然后調(diào)用scroll函數(shù)。對函數(shù)scroll函數(shù)的調(diào)用會導(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ā)生的事件。其中最重要的是列表項的選中事件。我們需要提供接口讓程序員能夠添加事件監(jiān)控器(listener)來監(jiān)控發(fā)生的事件,并且一旦發(fā)生事件,我們需要通知監(jiān)控器。
首先,我們添加一個成員來保存添加的事件監(jiān)控器:
Vector selectionListeners = new Vector();
?
我們再增加一個函數(shù)addSelectionListener,讓程序員可以添加監(jiān)控器
public void addSelectionListener(SelectionListener listener) {selectionListeners.addElement(listener);}
在我們前面的代碼中,我們注意到每次選擇項改變,我們都會調(diào)用selectionChanged函數(shù)。下面是selectionChanged函數(shù)代碼。這里,我們會生成一個SelectionEvent事件,并且逐個調(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)也日益成為軟件重要的部分,它是的殘疾人也能夠方便的使用我們的軟件。美國已經(jīng)立法,不符合Accessibility規(guī)范的軟件不能夠在政府部門銷售。我們開發(fā)的控件也需要支持Accessibility.下面的代碼使我們的控件有Accessibility支持。其中最重要的是getRole和getValue函數(shù)。我們的控件是從Canvas繼承,我們在getRole函數(shù)中返回ACC.ROLE_LIST,這樣我們的控件才能讓屏幕閱讀軟件將我們的控件作為列表控件對待。
Accessible accessible = getAccessible();accessible.addAccessibleControlListener(new AccessibleControlAdapter() {public void getRole(AccessibleControlEvent e) {int role = 0;int childID = e.childID;if (childID == ACC.CHILDID_SELF) {role = ACC.ROLE_LIST;} else if (childID >= 0 && childID < colors.size()) {role = ACC.ROLE_LISTITEM;}e.detail = role;}public void getValue(AccessibleControlEvent e){int childID = e.childID;if (childID == ACC.CHILDID_SELF) {e.result = getText();} else if (childID >= 0 && childID < colors.size()) {e.result = (String)colorNames.get(childID);}}public void getChildAtPoint(AccessibleControlEvent e) {Point testPoint = toControl(new Point(e.x, e.y));int childID = ACC.CHILDID_NONE;childID = (testPoint.y - cy)/lineHeight; if (childID == ACC.CHILDID_NONE) {Rectangle location = getBounds();location.height = location.height - getClientArea().height;if (location.contains(testPoint)) {childID = ACC.CHILDID_SELF;}}e.childID = childID;}public void getLocation(AccessibleControlEvent e) {Rectangle location = null;int childID = e.childID;if (childID == ACC.CHILDID_SELF) {location = getBounds();}if (childID >= 0 && childID < colors.size()) {location = new Rectangle(cx,childID*lineHeight+cy,maxX,lineHeight);}if (location != null) {Point pt = toDisplay(new Point(location.x, location.y));e.x = pt.x;e.y = pt.y;e.width = location.width;e.height = location.height;}}public void getChildCount(AccessibleControlEvent e) {e.detail = colors.size();}public void getState(AccessibleControlEvent e) {int state = 0;int childID = e.childID;if (childID == ACC.CHILDID_SELF) {state = ACC.STATE_NORMAL;} else if (childID >= 0 && childID < colors.size()) {state = ACC.STATE_SELECTABLE;if (isFocusControl()) {state |= ACC.STATE_FOCUSABLE;}if (rowSel == childID) {state |= ACC.STATE_SELECTED;if (isFocusControl()) {state |= ACC.STATE_FOCUSED;}}}e.detail = state;}});
最后,我們需要提供一些方法方便程序員使用我們的控件。
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ā)的控件的使用也是非常簡單的。
CustomList customlist = new CustomList( parent, SWT.V_SCROLL | SWT.H_SCROLL );customlist.add(SWT.COLOR_BLACK,"BLACK");customlist.add(SWT.COLOR_BLUE,"BLUE");customlist.setSelection(1);customlist.setSize(400,400);customlist.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
?注意:添加addTraverseListener時也得添加addListener(SWT.KeyDown)監(jiān)聽,不然的話,Tab鍵的Focus會不支持;
?
整個程序完整的代碼請參考如下:
/** Created on 2005-8-27**/
import java.util.Vector;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
import org.eclipse.swt.accessibility.Accessible;
import org.eclipse.swt.accessibility.AccessibleControlAdapter;
import org.eclipse.swt.accessibility.AccessibleControlEvent;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ScrollBar;/*** @author lq* */
public class ColorList extends Canvas {static int COLORS[] = { SWT.COLOR_RED, SWT.COLOR_GREEN, SWT.COLOR_BLUE,SWT.COLOR_MAGENTA, SWT.COLOR_YELLOW, SWT.COLOR_CYAN,SWT.COLOR_DARK_RED, SWT.COLOR_DARK_GREEN, SWT.COLOR_DARK_BLUE,SWT.COLOR_DARK_MAGENTA, SWT.COLOR_DARK_YELLOW, SWT.COLOR_DARK_CYAN };static String COLORSNAME[] = { "紅色", "綠色", "藍(lán)色", "紫色", "黃色","青色", "暗紅色", "暗綠色", "暗藍(lán)色", "暗紫色","暗黃色", "暗青色" };Vector colors = new Vector();Vector colorNames = new Vector();int rowSel = -1;int oldRowSel = -1;int cx, cy;int maxX = 200, maxY;int lineHeight = 18;Vector selectionListeners = new Vector();public ColorList(Composite parent, int style) {super(parent, style);init();}void init() {cx = 0;cy = 0;addPaintListener(new PaintListener() {public void paintControl(PaintEvent e) {GC gc = e.gc;Point size = getSize();int beginx = e.x;int beginy = (e.y / lineHeight) * lineHeight;int beginLine = (e.y - cy) / lineHeight;int endLine = beginLine + e.height / lineHeight + 1;if (endLine > getItemCount())endLine = getItemCount();for (int i = beginLine; i < endLine; i++) {boolean selected = false;if (i == rowSel)selected = true;onPaint(gc, i, cx, beginy + (i - beginLine) * lineHeight,selected);}}});addMouseListener(new MouseListener() {public void mouseDoubleClick(MouseEvent e) {}public void mouseDown(MouseEvent e) {int row = (e.y - cy) / lineHeight;if (row >= 0) {oldRowSel = rowSel;rowSel = row;}if (oldRowSel != rowSel) {((Canvas) e.getSource()).redraw(cx, (e.y / lineHeight)* lineHeight, maxX, lineHeight, false);((Canvas) e.getSource()).redraw(cx, (oldRowSel + cy/ lineHeight)* lineHeight, maxX, lineHeight, false);}selectionChanged();}public void mouseUp(MouseEvent e) {}});addListener(SWT.KeyDown, new Listener() {public void handleEvent(Event event) {switch (event.keyCode) {case SWT.ARROW_UP: // up arrow keyif (rowSel != 0) {oldRowSel = rowSel;rowSel--;if (oldRowSel != rowSel) {((Canvas) event.widget).redraw(cx, rowSel*lineHeight + cy, maxX, lineHeight*2, false);}if (rowSel < -cy / lineHeight) {ScrollBar bar = ((Canvas) event.widget).getVerticalBar();bar.setSelection(bar.getSelection() - lineHeight);scrollVertical(bar);}selectionChanged();}break;case SWT.ARROW_DOWN: // down arror keyif (rowSel < colors.size() - 1) {oldRowSel = rowSel;rowSel++;if (oldRowSel != rowSel) {((Canvas) event.widget).redraw(cx, (rowSel + cy/ lineHeight)* lineHeight, maxX, lineHeight, false);((Canvas) event.widget).redraw(cx, (oldRowSel + cy/ lineHeight)* lineHeight, maxX, lineHeight, false);}if (rowSel >= (((Canvas) event.widget).getClientArea().height - cy)/ lineHeight) {ScrollBar bar = ((Canvas) event.widget).getVerticalBar();if (bar != null) {bar.setSelection(bar.getSelection()+ lineHeight);scrollVertical(bar);}}selectionChanged();}break;}}});addControlListener(new ControlAdapter() {public void controlResized(ControlEvent event) {Point size = getSize();maxX = size.x * 3 / 2;maxY = colors.size() * lineHeight;resizeScrollBars();}});addFocusListener(new FocusListener() {public void focusGained(FocusEvent e) {((Canvas) e.getSource()).redraw(cx, rowSel * lineHeight, maxX,lineHeight, true);}public void focusLost(FocusEvent e) {((Canvas) e.getSource()).redraw(cx, rowSel * lineHeight, maxX,lineHeight, true);}});addTraverseListener(new TraverseListener() {public void keyTraversed(TraverseEvent e) {if (e.detail == SWT.TRAVERSE_TAB_NEXT|| e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {e.doit = true;}};});ScrollBar bar = getHorizontalBar();if (bar != null) {bar.addSelectionListener(new SelectionAdapter() {public void widgetSelected(SelectionEvent event) {scrollHorizontal((ScrollBar) event.widget);}});}bar = getVerticalBar();if (bar != null) {bar.addSelectionListener(new SelectionAdapter() {public void widgetSelected(SelectionEvent event) {scrollVertical((ScrollBar) event.widget);}});}resizeScrollBars();addAccessibility();}private void addAccessibility(){Accessible accessible = getAccessible();accessible.addAccessibleControlListener(new AccessibleControlAdapter() {public void getRole(AccessibleControlEvent e) {int role = 0;int childID = e.childID;if (childID == ACC.CHILDID_SELF) {role = ACC.ROLE_LIST;} else if (childID >= 0 && childID < colors.size()) {role = ACC.ROLE_LISTITEM;}e.detail = role;}public void getValue(AccessibleControlEvent e){int childID = e.childID;if (childID == ACC.CHILDID_SELF) {e.result = getText();} else if (childID >= 0 && childID < colors.size()) {e.result = (String)colorNames.get(childID);}}public void getChildAtPoint(AccessibleControlEvent e) {Point testPoint = toControl(new Point(e.x, e.y));int childID = ACC.CHILDID_NONE;childID = (testPoint.y - cy)/lineHeight; if (childID == ACC.CHILDID_NONE) {Rectangle location = getBounds();location.height = location.height - getClientArea().height;if (location.contains(testPoint)) {childID = ACC.CHILDID_SELF;}}e.childID = childID;}public void getLocation(AccessibleControlEvent e) {Rectangle location = null;int childID = e.childID;if (childID == ACC.CHILDID_SELF) {location = getBounds();}if (childID >= 0 && childID < colors.size()) {location = new Rectangle(cx,childID*lineHeight+cy,maxX,lineHeight);}if (location != null) {Point pt = toDisplay(new Point(location.x, location.y));e.x = pt.x;e.y = pt.y;e.width = location.width;e.height = location.height;}}public void getChildCount(AccessibleControlEvent e) {e.detail = colors.size();}public void getState(AccessibleControlEvent e) {int state = 0;int childID = e.childID;if (childID == ACC.CHILDID_SELF) {state = ACC.STATE_NORMAL;} else if (childID >= 0 && childID < colors.size()) {state = ACC.STATE_SELECTABLE;if (isFocusControl()) {state |= ACC.STATE_FOCUSABLE;}if (rowSel == childID) {state |= ACC.STATE_SELECTED;if (isFocusControl()) {state |= ACC.STATE_FOCUSED;}}}e.detail = state;}});}void onPaint(GC gc, int row, int beginx, int beginy, boolean isSelected) {Color initColor = gc.getBackground();Color initForeColor = gc.getForeground();if (isSelected) {gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION));gc.fillRectangle(beginx, beginy, maxX, lineHeight);gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));} else {gc.setBackground(initColor);}gc.drawString((String) colorNames.get(row), beginx + 40, beginy);Color color = Display.getCurrent().getSystemColor(((Integer) colors.get(row)).intValue());gc.setBackground(color);gc.fillRectangle(beginx + 2, beginy + 2, 30, lineHeight - 4);gc.setBackground(initColor);gc.setForeground(initForeColor);if (isFocusControl() && isSelected)gc.drawFocus(cx, beginy, maxX, lineHeight);}void resizeScrollBars() {Rectangle clientArea = getClientArea();ScrollBar hbar = getHorizontalBar();if (hbar != null) {hbar.setMaximum(maxX);hbar.setThumb(clientArea.width);hbar.setPageIncrement(clientArea.width);}ScrollBar vbar = getVerticalBar();if (vbar != null) {vbar.setMaximum(maxY);vbar.setThumb(clientArea.height);vbar.setPageIncrement(clientArea.height);vbar.setIncrement(lineHeight);if (clientArea.height >= lineHeight * getItemCount() + 2)vbar.setVisible(false);elsevbar.setVisible(true);}}void scrollHorizontal(ScrollBar scrollBar) {Rectangle bounds = getClientArea();int x = -scrollBar.getSelection();if (x + maxX < bounds.width) {x = bounds.width - maxX;}scroll(x, cy, cx, cy, maxX, maxY, false);cx = x;}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;}public Point computeSize(int wHint, int hHint, boolean changed) {int width = 300, height = lineHeight * (getItemCount())+50;if (wHint != SWT.DEFAULT)width = wHint;if (hHint != SWT.DEFAULT)height = hHint;return new Point(width + 2, height + 2);}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));}public void setDefault() {for (int i = 0; i < COLORS.length; i++) {colors.add(new Integer(COLORS[i]));colorNames.add(COLORSNAME[i]);}}public void addSelectionListener(SelectionListener listener) {selectionListeners.addElement(listener);}public void removeImageClickedListener(SelectionListener listener) {selectionListeners.removeElement(listener);}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);}}public String getText(){if(rowSel>=0)return (String)colorNames.get(rowSel);else return null;}
}
轉(zhuǎn)載于:https://www.cnblogs.com/huadoumi/p/5160300.html
總結(jié)
以上是生活随笔為你收集整理的开发Eclipse自定义控件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 脐带血多少钱啊?
- 下一篇: 前端解决跨域问题的8种方案(最新最全)