没有合适的资源?快使用搜索试试~ 我知道了~
自定义SWT组件文档,源自Eclispe 官方
需积分: 0 1 下载量 130 浏览量
2022-07-21
14:35:51
上传
评论
收藏 1.07MB PDF 举报
温馨提示
试读
29页
SWT提供的标准组件毕竟有限,很多时候我们都需要自定义组件。本文介绍了自定以SWT组件的方法,可以创建独立的也可以创建复合的。 文章 地址 : https://www.eclipse.org/articles/Article-Writing%20Your%20Own%20Widget/Writing%20Your%20Own%20Widget.htm
资源推荐
资源详情
资源评论
2022/7/21 14:30
Writing Your Own Widget
https://www.eclipse.org/articles/Article-Writing Your Own Widget/Writing Your Own Widget.htm
1/29
Copyright © 2001 Object Technology International, Inc.
Eclipse Corner Article
Creating Your Own Widgets using SWT
Summary
When writing applications, you typically use the standard widgets
provided by SWT. On occasion, you will need to create your own
custom widgets. For example, you might want to add a new type of
widget not provided by the standard widgets, or extend the
functionality of an existing widget. This article explains the different
SWT extension strategies and shows you how to use them.
By Steve Northover & Carolyn MacLeod, OTI
March 22, 2001
Creating Your Own Widgets
Overview
When writing applications, you typically use the standard widgets provided by SWT.
On occasion, you will need to create your own custom widgets. There are several
reasons that you might want to do this:
· To add a new type of widget not provided by the standard widgets
· To extend the functionality of an existing widget
Custom widgets are created by subclassing in the existing widget class hierarchy.
Portability Issues
It is very important to think about portability before writing a custom widget. SWT
can be extended in the following ways:
· Write a new widget that is 100% Java™ portable
· Extend an existing widget in a 100% Java portable manner
· Write a new widget that wraps an existing native widget – not portable
· Extend an existing widget by calling natives – not portable
In addition, a combination of these can be used on different platforms:
2022/7/21 14:30
Writing Your Own Widget
https://www.eclipse.org/articles/Article-Writing Your Own Widget/Writing Your Own Widget.htm
2/29
· Write a new widget that wraps an existing native widget on one platform, but is
100% Java portable on other platforms
· Extend an existing widget by calling natives on one platform, but call 100%
Java portable code on other platforms
This of course involves implementing the widget twice – using native calls on the
one platform and portable code on the others – while maintaining the same API for
both.
Each SWT platform is shipped with both a shared library (for example, a DLL on
Windows®) and a jar (for the Java class files). The shared library contains all of the
native function required for SWT, but it was not meant to be a complete set of the
functions available on the platform. Thus to expose native function or native widgets
that were not exposed by SWT, you need to write your own shared library. If you are
using a combination of native code on one platform and portable code on another,
make sure you call your shared library on the platform with the native widget, and
your jar on the platform with the portable widget.
One final note: SWT’s interface to its shared libraries is internal SWT code. It was
not meant to provide a framework for applications to access all possible native
function on all platforms – that would be a daunting task. One of the purposes of this
document is to show how you can integrate C code with SWT, not model the
operating system. As such, the approach taken to writing natives in this document is
different from the approach taken by SWT.
Writing Portable Widgets
The SWT library provides two widget classes that are typically used as the basis for
a custom 100% Java portable widget:
· Canvas - to create basic widgets
· Composite - to create compound widgets
Basic Widgets
Basic widgets do not contain any other widgets, and are not built from any other
widgets. Basic widgets draw themselves. An example of a basic widget is Button.
Another example is Text. To create a custom basic widget, subclass Canvas.
Compound Widgets
Compound widgets contain other widgets, and/or are composed of other widgets. An
example of a compound widget is Combo. It contains a Text, a Button and a List.
Another example is Group. It can contain any number of children. To create a custom
compound widget, subclass Composite.
The astute reader may have noticed that Canvas is actually a subclass of Composite.
This is an artifact of the underlying implementation. We treat Canvas as something
you draw on and Composite as something that has children. Therefore the rule for
deciding which class to subclass is this: If your widget has or will have children,
subclass Composite. If your widget does not have and never will have children,
subclass Canvas.
2022/7/21 14:30
Writing Your Own Widget
https://www.eclipse.org/articles/Article-Writing Your Own Widget/Writing Your Own Widget.htm
3/29
Note also that we do not distinguish between a compound widget that is intended to
contain and lay out children, and one that is merely composed of other widgets. Both
will be a subclass of Composite, and as such we are describing implementation,
rather than type, inheritance. When writing 100% Java portable widgets, we can
think of Composite as the portable entry point into the SWT class hierarchy for all
compound widgets, and Canvas as the portable entry point into the SWT class
hierarchy for all basic widgets, regardless of widget type.
Basic Widget Example
Imagine we are building an application where we need a widget that displays an
image with a line of text to the right, something like this:
Since we plan to draw both the image and the text, we subclass Canvas.
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.events.*;
public class PictureLabel extends Canvas {
Image image;
String text;
}
Our widget needs to be created. To do this, we must write at least one constructor.
Because widgets in SWT cannot be created without a parent, the constructor must
take at least one argument that is the parent. The convention in SWT is to have a
constructor with two arguments, parent and style. Style bits are used to control the
look of widgets. Neither the parent nor the style bits can be changed after the widget
is created. Your widget can use style bits too.
PictureLabel(Composite parent, int style) {
super(parent, style);
}
The parent of any widget must be a Composite. The style is an integer, where some
bits are already used by the system. For example, SWT.BORDER will cause a Canvas
to have a border.
Next we need to initialize our widget. The convention in SWT is to do all
initialization in the constructor. Certainly, any initialization that requires the parent or
the style bits must be done here. We have decided that our PictureLabel widget will
default to a white background, so we need to add a Color field, allocate a Color, and
initialize the background.
public class PictureLabel extends Canvas {
Image image;
String text;
2022/7/21 14:30
Writing Your Own Widget
https://www.eclipse.org/articles/Article-Writing Your Own Widget/Writing Your Own Widget.htm
4/29
Color white;
PictureLabel(Composite parent, int style) {
super(parent, style);
white = new Color(null, 255, 255, 255);
setBackground(white);
Colors are graphics resources that must be disposed. How can we dispose of the
white color that we allocated? We add a dispose listener. Every widget provides
notification when it is destroyed. We add the dispose listener in the constructor.
addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
white.dispose();
}
});
}
}
Note: Do not just override dispose() to release the color. This only works in the case
where dispose is actually sent to the widget. When the shell is disposed this does not
happen, so overriding dispose will leak the color. To ensure that your widget is
informed of an event no matter how it was generated, add an event listener instead of
overriding methods that generate events.
Our widget is created and initialized, and it can be destroyed without leaking
graphics resources. Now it needs some functionality. We need to draw the image and
the text, and this will require another listener: the paint listener. Implementing a
widget often requires adding many listeners. We could implement the listener
interfaces as part of our new widget class, but that would make the interface methods
public in our class. Instead, the SWT convention is to use anonymous inner classes to
forward the functionality to non-public methods of the same name. For consistency,
we will rewrite the dispose listener to follow this convention, moving the color
dispose code into the widgetDisposed method. We write the paint listener the same
way.
addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
PictureLabel.this.widgetDisposed(e);
}
});
addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
PictureLabel.this.paintControl(e);
}
});
By choosing the same names, we have the option of easily implementing the
interfaces if we decide to do so later. Here is the paintControl method to draw the
widget.
void paintControl(PaintEvent e) {
GC gc = e.gc;
int x = 1;
if (image != null) {
gc.drawImage(image, x, 1);
2022/7/21 14:30
Writing Your Own Widget
https://www.eclipse.org/articles/Article-Writing Your Own Widget/Writing Your Own Widget.htm
5/29
x = image.getBounds().width + 5;
}
if (text != null) {
gc.drawString(text, x, 1);
}
}
Now we can draw the image and the text, but we need to let the user set them. So we
write set and get methods for each of them.
public Image getImage() {
return image;
}
public void setImage(Image image) {
this.image = image;
redraw();
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
redraw();
}
The get methods are trivial. They simply answer the fields. The set methods set the
fields and then redraw the widget to show the change. The easiest way to do this is to
damage the widget by calling redraw(), which queues a paint event for the widget.
This approach has the advantage that setting both the image and the text will cause
only one paint event because multiple paints are collapsed in the event queue.
We are not done yet. Our widget does not know its preferred size. This information is
needed in order to lay out the widget. In our case, the best size is simply the size of
the text plus the size of the image, plus a little bit of space in between. Also, we will
add a 1 pixel margin all the way around.
To return the preferred size of the widget, we must implement the computeSize
method. The computeSize method can be quite complicated. Its job is to calculate
the preferred size of the widget based on the current contents. The simplest
implementation ignores the arguments and just computes the size.
public Point computeSize(int wHint, int hHint, boolean changed) {
int width = 0, height = 0;
if (image != null) {
Rectangle bounds = image.getBounds();
width = bounds.width + 5;
height = bounds.height;
}
if (text != null) {
GC gc = new GC(this);
Point extent = gc.stringExtent(text);
gc.dispose();
width += extent.x;
height = Math.max(height, extent.y);
}
剩余28页未读,继续阅读
资源评论
小子宝丁
- 粉丝: 712
- 资源: 34
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功