[摘要]e.detail == SWT.TRAVERSE_TAB_PREVIOUS) e.doit = true; ; ); 很多时候,我们需要有滚动条的支持。对于滚动条,我们只...
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);
}
});
}
下面是函数scrollVertical的代码。一旦用户对滚动条操作,我们就可以计算出要滚动的区域,然后调用scroll函数。对函数scroll函数的调用会导致相应区域的重绘。
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;
}
现在我们的程序已经基本成形了,我们来进一步完善它。由于我们开发的控件是提供给程序员的,我们需要提供接口,让外部知道控件中发生的事件。其中最重要的是列表项的选中事件。我们需要提供接口让程序员能够添加事件监控器(listener)来监控发生的事件,并且一旦发生事件,我们需要通知监控器。
首先,我们添加一个成员来保存添加的事件监控器:
Vector selectionListeners = new Vector();
我们再增加一个函数addSelectionListener,让程序员可以添加监控器
public void addSelectionListener(SelectionListener listener) {
selectionListeners.addElement(listener);
}
在我们前面的代码中,我们注意到每次选择项改变,我们都会调用selectionChanged函数。下面是selectionChanged函数代码。这里,我们会生成一个SelectionEvent事件,并且逐个调用事件监控器的widgetSelected方法。这样别人就可以监听到我们的事件了。
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);
}
}
现在辅助功能(Accessibility)也日益成为软件重要的部分,它是的残疾人也能够方便的使用我们的软件。美国已经立法,不符合Accessibility规范的软件不能够在政府部门销售。我们开发的控件也需要支持Accessibility.下面的代码使我们的控件有Accessibility支持。其中最重要的是getRole和getValue函数。我们的控件是从Canvas继承,我们在getRole函数中返回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
关键词:开发Eclipse下的自定义控件