??xml version="1.0" encoding="utf-8" standalone="yes"?>
当一个GCҎ在一个Drawabel对象上画Z个图案,它仅执行q个paintingq程一ơ。如果用h变对象尺寸或是用另一个窗口去覆盖它,则图形会被消除。因此,应用E序能否在外界事件媄响下l持其外观这一点相当重要?br />
graphic context是在GCcM的,GC对象是附着于现存的Controls?br />
要创Z个graphically oriented的应用程序,首先要创建graphic contextQƈ其与一个component相关联,q两步都可通过GC的constructor来实现。共?个构造函敎ͼ见下Q?br />1. GC(Drawable)--Creates a GC and configures it for the Drawable object
2. GC(Drawable, int)--Creates and configures a GC and sets the text-display styleQ第二个参数可以是RIGHT_TO_LEFT或LEFT_TO_RIGHTQ默认|;
W一个参数需要实现Drawable接口的对象, 此接口包含了与graphic context.内部相联pȝҎ。SWT提供了三个实现Drawable接口的类QImage, Device, ?Control.
Control子类虽然都能包含囑ŞQ但只有一个类是特别适合GC对象的:Canvas。它不仅提供了一个Composite的containment propertyQ还可以用一pd的风格来定义囑Ş在此区域内如何显C?br />
CZQ?/u>
package com.swtjface.Ch7;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
public class DrawExample
{
public static void main (String [] args)
{
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Drawing Example");
Canvas canvas = new Canvas(shell, SWT.NONE);
canvas.setSize(150, 150);
canvas.setLocation(20, 20);//在shell中创建canvas
shell.open ();
shell.setSize(200,220);
GC gc = new GC(canvas);//在canvas中创?/font>graphic context
gc.drawRectangle(10, 10, 40, 45);
gc.drawOval(65, 10, 30, 35);
gc.drawLine(130, 10, 90, 80);
gc.drawPolygon(new int[] {20, 70, 45, 90, 70, 70});
gc.drawPolyline(new int[] {10,120,70,100,100,130,130,75});
gc.dispose();//释放Color对象
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
有两炚w要注意:1.在调用shell.open()之前构徏Canvas对象Q然后在调用shell.open()之后创徏和用GC对象
2.在用完之后一定要立即释放GC object
如上例所CGC提供了一pd在Drawable对象上画囑Ş的方法,如下Q?br />
但是上例中有个问题:当shell被变灰过或者最化q之后,囑Ş׃被擦厅R所以我们需要解决的事,无论window怎么变化Q图形都保持可见。因此SWT在一?/span>Drawable对象被刷新后让你自行控制。这个更新的q程pUCؓpainting?/span>
Painting and PaintEvents
q些外部事g被称为PaintEventsQ接收它们的E序接口是PaintListener。一个Control在Q何时候当其外观被应用E序或是外界zd改变都会触发一个PaintEvent。这些类对于事g和监听器的用方式都和我们在W四章内提到的类伹{由于PaintListener只有一个事件处理方法,所以不需要用adapterc?br />
Canvas canvas = new Canvas(shell, SWT.NONE);
canvas.setSize(150, 150);
canvas.setLocation(20, 20);
canvas.addPaintListener(new PaintListener()
{
public void paintControl(PaintEvent pe)
{
GC gc = pe.gc;//每一个PaintEvent对象都包含有其自qGC
gc.drawPolyline(new int[] {10,120,70,100,100,130,130,75});
}
});
shell.open();
每一个PaintEvent对象都包含有其自qGCQ主要有2个原因:1.因ؓq个GC instance是由事g产生的,所以PaintEvent会负责释放他?.应用E序可以在shell open之前创徏GC,q样可以使图形在一个独立的cM被创建?/font>
SWT?/span>PaintListener接口内优?/span>paintingq程,SWT的开发者强烈徏?/span>Control?/span>painting仅对PaintEvent作出反应。如果一个应用程序因为其他原因必L新其囑ŞQ则他们推荐使用control?/span>redraw()ҎQ这会在队列中加入一?/span>painth。之后,你可以调?/span>update()Ҏ来处理所有的l定于该对象?/span>painth?br />
需要牢记的是,虽然对于Control对象推荐在一个PaintListener内paintingQ但是由于Device和Image对象q不能在该接口内使用。如果你需要在一个image或device内生成图形,你必d独地生成一个GC对象q在使用l束后将光毁?/span>
]]>
computeSize()
protected Point computeSize(Composite composite,
int wHint, int hHint,
boolean flushCache)
{
Point maxDimensions =
calculateMaxDimensions(composite.getChildren());
int stepsPerHemisphere =
stepsPerHemisphere(composite.getChildren().length);
int maxWidth = maxDimensions.x;
int maxHeight = maxDimensions.y;
int dimensionMultiplier = (stepsPerHemisphere + 1);
int controlWidth = maxWidth * dimensionMultiplier;
int controlHeight = maxHeight * dimensionMultiplier;
int diameter = Math.max(controlWidth, controlHeight);
Point preferredSize = new Point(diameter,
diameter);
... // code to handle case when our calculations
// are too large
return preferredSize;
}
参数Q?br />1.composite--The object we’re going to populate. At the time this method is called, it has children, but neither the composite nor the children have been sized or positioned on the screen.
2.wHint and hHint--layout所需的最大长宽。若带有参数SWT.DEFAULT,表示此layout可以随意使用use whatever sizes it decides it needs.
3.flushCache--作ؓflagQto tell the layout whether it’s safe to use any cached values that it may be maintaining.
computeSize()的目的主要在于计我们要layout的composite有多?br />layout()
…?br />
除了MenuManager所用的ContributionItems之外Q还有一个新的ContributionItemQ只能被ToolBarManager使用——ControlContribution。这个类可将M能被用于toolbar的Control打包q去?br />
要用ControlContributionc,必须要实现抽象方法createControl().
toolBarManager.add(new ControlContribution("Custom") {
protected Control createControl(Composite parent) {
SashForm sf = new SashForm(parent, SWT.NONE);
Button b1 = new Button(sf, SWT.PUSH);
b1.setText("Hello");
Button b2 = new Button(sf, SWT.PUSH);
b2.setText("World");
b2.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
System.out.println("Selected:" + e);
}
});
return sf;
}
});
如果你希望有M的事件发生,必须在你的controls上实现SelectionListeners
如果你不想ToolBarManager来创建toolbar的话Q可以手动创建,需要用到ToolBar和ToolItemc?
Toolbar
是一个composite controlQ包含多个ToolItems.Toolbar由多个小图标按钮l成Q一般是16-by-16bitmap囄。每个按钮都对应一个ToolItem。Toolbar可以是水q的也可以是垂直的,默认为水q?br />
ToolItem
每一个ToolItem都有一个图片,如果没有Q默认ؓU色方块。When the user selects a ToolItem from the menu, it broadcasts the event to any registered SelectionListeners.Your application should register a listener with each ToolItem and use that listener to perform whatever logic corresponds to the menu item.
两个重要的接口:IDocument和ITextViewer。JFace为其提供了默认的实现?br />
一?span lang="en-US">IDocument的实例持有被~辑的真实的文本信息。它的主要实现是DocumentcRAbstractDocument提供了部分实玎ͼ你可通过l承它来d自己的实现。IDocument允许通过IDocumentListener接口来获取内容编辑的通知?br />
IDocumentq提供了以下功能
Positions
可以l每一个text区域分配一个记h作ؓ它的Position。当被指定给某个ducument时一个Position对象有an offset and a length of text。如果document的text被更新的话,Position也会同步更新Q所以他永远都是指向同一D|字。PositioncLw提供了一些基本的功能Q可通过l承他来完善更多有用的功能?br />
Partition content types
每个document׃个或多个partitionsl成Q通过ITypedRegion接口来表现。每一个partition可以有各自的内容cdQ如plain text, rich text, or HTML。要使用它,你要创徏一个IDocumentPartitioner然后assignl你的document,然后document的partitioner׃负责响应Ҏ定位|内容类型的查询Q它必须通过实现computePartitioning()来返回包含此document中所有ITypedRegions的一个数l。不需要实C自己的document partitioner。如果没有创建,整个document是一个区域,cd为IDocument.DEFAULT_CONTENT_TYPE?br />
Searching
IDocument通过search()提供了搜索的功能。不支持regular expressions or other patternsQ但提供了search start location,direction, and case sensitivity and whether to match whole words only.
ITextViewer一个标准的text widget转换成一个基于document的text widget
ITextViewer的默认实现是TextViewerQ它使用StyledText来显C数据。ITextViewer支持text modifications的listenerQ也支持visual eventsQ如改变viewportQ即text的当前可视区域)的监听器?br />
虽然作ؓITextViewer的默认应用,如果你想要修ҎC,TextViewer允许你直接accessStyledTextQ但你用TextPresentationQ因为它可以攉该文档中带有的各个不同的StyleRanges?br />
ITextViewerq支持很多不同类型的插gQ可用来修改widget的行为。可以被customized的功能有Q?br />1.通过IUndoManager来支持undo
2.通过ITextDoubleClickStrategy来支持对鼠标双击的处?br />3.通过IAutoIndentStrategy来支持文本的自动~进
4.通过ITextHover来实玎ͼ当鼠标停留在document的一个section上时Q显Ctext.
要用上q插Ӟ你需要分配一个适当的接口实例给text viewerQ然后调用activatePlugins().
如下列出了org.eclipse.jface.text的子包及其作?br />
package com.swtjface.Ch5;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
public class Ch5Capitalizer extends Composite {
public Ch5Capitalizer(Composite parent) {
super(parent, SWT.NONE);
buildControls();
}
private void buildControls() {
this.setLayout(new FillLayout());
Text text = new Text(this, SWT.MULTI | SWT.V_SCROLL);
text.addVerifyListener(new VerifyListener() { //每当text被改变,M以注册的VerifyListeners便会被调用。此处每按一ơ键盘,此方法就被调用。如果是同时输入多个字符Q也调用一?/font>
public void verifyText(VerifyEvent e) {
if( e.text.startsWith("1") ) {
e.doit = false;
} //如果文本?开_即不允许~辑
else {
e.text = e.text.toUpperCase();
}
}
});
}
}
Text的重要方法,见下?br />
insert()--doesn’t allow you to insert text into the existing content.
StyledText包含了一pd的应用到该小部g的预定义的动作,q些是常规的东西如:剪切、粘贴、移动至下一个词、移动至文末。代表这些动作的帔R?/span>org.eclipse.swt.customE序包中?/span>STcM有定义。这些常量在两种情况下发挥功效:首先Q你可以使用它们E序性地使用invokeAction()Ҏ调用M的这些方法;其次Q你也可以?/span>setKeyBinding()Ҏ来将它们l定于键击行为?/span>setKeyBinding()选定一个键Q可以通过诸如Shift或是Ctrl之类的编辑键来修?/span>SWT帔R之一Q绑定于指定的动作。如下的例子中组合键Ctrl-Ql定于粘贴动作。引h意的是这q不意味着会将默认键的l定清除Q该两个l定都会生效?/span>
相对于Text而言Q还d了drawing line backgrounds and line styles的事Ӟ可以通过此事件来改变整行的style或背景颜艌Ӏ注意:如果使用了LineStyleListener,׃能在StyledText实例上调用get/setStyleRange()Q?如果使用了LineBackgroundListenerQ那你就不能调用getLineBackground() or setLineBackground().
可以通过使用一个StyledText的StyleRanges来改变显C的风格
StyleRange
StyledText通过使用StyleRangecL理当前所昄的不同styles。其所有的栏位都是public的可随意修改Q但是要一直到当此StyledText实例的setStyleRange()被调用之后才会生效?br />
StyleRanges通过开始偏U量和长度来讑֮text的区域范围?/font>
StyleRange可设定背景和前景Ԍ默认为nullQ还可设定字体,SWT.NORMAL 或者SWT.BOLD.
similarTo()可用来判断两个StyleRange实例是否有同L前景、背景和字体?br />
当我们保存text之后Q可通过styledText.getStyleRanges()来获取style信息Q此函数会返回an array of StyleRange
toggleBold()--已输入的文本在bold和normal之间切换Q是被一个KeyListener调用的,此KeyListener会监听F1是否被按?br />
A StyledText example
复制、粘贴功能不需要通过代码便可使用Q是和platform的标准键盘快h式相兌?br />
ExtendedModifyListener和ModifyListener不同Q前者提供了关于what was done的eventl节Q而后者只是当~辑懂作产生时notify,不会d的辨别到底何种修改发生了?br />
package com.swtjface.Ch5;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
public class Ch5Undoable extends Composite {
private static final int MAX_STACK_SIZE = 25;
private List undoStack;
private List redoStack;
private StyledText styledText;
public Ch5Undoable(Composite parent) {
super(parent, SWT.NONE);
undoStack = new LinkedList();
redoStack = new LinkedList();
buildControls();
}
private void buildControls() {
this.setLayout(new FillLayout());
styledText = new StyledText(this, SWT.MULTI | SWT.V_SCROLL);
styledText.addExtendedModifyListener(
new ExtendedModifyListener() { //每次text被编辑的时候,都会调用此listener
public void modifyText(ExtendedModifyEvent event) {
String currText = styledText.getText();
String newText = currText.substring(event.start,
event.start + event.length); //获得新插入的文本
if( newText != null && newText.length() > 0 ) {
if( undoStack.size() == MAX_STACK_SIZE ) {
undoStack.remove( undoStack.size() - 1 );
}
undoStack.add(0, newText);//新插入的文本保存到undoStack?/font>
}
}
}); //关键部分
styledText.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
switch(e.keyCode) {
case SWT.F1:
undo(); break;
case SWT.F2:
redo(); break;
default: //ignore everything else
}
}
});
}
private void undo() {
if( undoStack.size() > 0 ) {
String lastEdit = (String)undoStack.remove(0);//得到要undo的字W?/font>
int editLength = lastEdit.length();
String currText = styledText.getText();
int startReplaceIndex = currText.length() - editLength;
styledText.replaceTextRange(startReplaceIndex, editLength, ""); //最后输入的字符替换成空
redoStack.add(0, lastEdit);//把最后的q个undo的字W加到redoStack?/font>
}
}
private void redo() {
if( redoStack.size() > 0 ) {
String text = (String)redoStack.remove(0);//得到要恢复的字符
moveCursorToEnd();
styledText.append(text);//要恢复的字W加x本的最?/font>
moveCursorToEnd();
}
}
private void moveCursorToEnd() {
styledText.setCaretOffset(styledText.getText().length());
}
}
Action--可以单的理解成一个命令,可以兌到菜单,工具条,以及按钮
Contribution--?/span>JFace里面Q一?/span>Action可以对应多个GUI对象Q这些对象就是所谓的Contribution Item. 有两个主要的Contributionc:ContributionItem和ContributionManagerQ它们都是抽象类Q靠其子cL实现事g的处理。承关p见下图
ContributionItem--引发事g的单独GUIlg
ContributionManager--产生包含ContributionItems的对?br />
ActionContributionItem--最重要Q在ApplicationWindow中创建和实施Q来一个actionq接xGUIQ它虽没有设定好的外观,但是依赖于你使用的fill()ҎQ却可以帮助一个按钮、菜单栏和工h的成?br />
另一个与Contribution协作的方法是通过ContributionManager,它的子类cM于ContributionItem的container。其中MenuManagerContributionItemsl合在窗口最高层菜单Q?ToolBarManager则将q些对象攑֜仅在菜单之下的toolbar中?/font>
Action是抽象类?/font>
package com.swtjface.Ch4;
import org.eclipse.jface.action.*;
import org.eclipse.jface.resource.*;
public class Ch4_StatusAction extends Action
{
StatusLineManager statman;
short triggercount = 0;
public Ch4_StatusAction(StatusLineManager sm)
{
super("&Trigger@Ctrl+T",
AS_PUSH_BUTTON);//在T字母之前?amp;W号意味着q个字母作动作的快捷键。而在TEXT领域内的“Ctrl+T”确保了当用户在同时按下Ctrl键和T键时该动作就会被Ȁ发?/font>
statman = sm;
setToolTipText("Trigger the Action");
setImageDescriptor(ImageDescriptor.createFromFile
(this.getClass(),"eclipse.gif"));
}
public void run() //每次当Ch4_StatusAction被生成,run()Ҏp调用
{
triggercount++;
statman.setMessage("The status action has fired. Count: " +
triggercount);
}
package com.swtjface.Ch4;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.jface.window.*;
import org.eclipse.jface.action.*;
public class Ch4_Contributions extends ApplicationWindow {
StatusLineManager slm = new StatusLineManager();
Ch4_StatusAction status_action = new Ch4_StatusAction(slm); //?font face="Verdana">StatusLineManager的对象作参数Q?/font>创徏了一?font face="Verdana">Ch4_StatusAction的实?/font>
ActionContributionItem aci = new ActionContributionItem(status_action); //?font face="Verdana" size="2">Ch4_StatusAction的对象作参数Q创ZActionContributionItem对象
public Ch4_Contributions() {
super(null); // 创徏?/font> ApplicationWindow对象
addStatusLine();
addMenuBar();
addToolBar(SWT.FLAT | SWT.WRAP); //在窗口上d了status line, menu, toolbar
}
protected Control createContents(Composite parent) {
getShell().setText("Action/Contribution Example");
parent.setSize(290,150); //讄了窗口的title和size
aci.fill(parent); // ActionContributionItem攑֜GUI中。因里的参数是Composite对象Q所以根据Action的STYLE属性来定。此处是ButtonQ因?font color="#0000ff">Ch4_StatusAction 的STYLE属性是AS_PUSH_BUTTON;
return parent;
}
public static void main(String[] args) {
Ch4_Contributions swin = new Ch4_Contributions();
swin.setBlockOnOpen(true);
swin.open();
Display.getCurrent().dispose();
}
protected MenuManager createMenuManager() {
MenuManager main_menu = new MenuManager(null);
MenuManager action_menu = new MenuManager("Menu");
main_menu.add(action_menu);
action_menu.add(status_action); //兌status_action.created and added to the menu in the form of a menu item
return main_menu;
}
protected ToolBarManager createToolBarManager(int style) {
ToolBarManager tool_bar_manager = new ToolBarManager(style);
tool_bar_manager.add(status_action); //兌status_action。created and added to the toolbar as a toolbar item.
return tool_bar_manager;
}
protected StatusLineManager createStatusLineManager() {
return slm;
}
}
两个途径来将ActionContributionItemd到GUIQ?br />1. 通过ContributionManager子类的add()Ҏ?br />Q?Q可接受Action对象的参敎ͼ从而间接的ContributionItem和ContributionManager兌。可多次执行
Q?Q可直接接受ActionContributionItem对象的参数。只可执行一?br />2.通过ActionContributionItemcȝfill()Ҏ。根据其参数的不同,所先是的组件也不同Q具体见下表Q?br />
Important methods of the Action class
Property methods for the Action class
DESCRIPTION--written to a status line to provide additional help.
Style methods for the Action class
如果ENABLED是FALSEQ则变灰。CHECKED主要用于radio和checkbox
Accelerator key / keyboard methods for the Action class
Accelerator keys--鼠标点击的键盘块h?/font>
Listener methods for the Action class
虽然JFace使用action代替了SWT的listener/event机制Q但是ActionocM然可以和listener协作来处理特定需求的事g?br />IPropertyChangeListener接口x客户自定义的PropertyChangeEvents,当所l的对象按照你所l的方式变成另一个对象时Q此事g被触发?br />
Miscellaneous methods of the Action class
1. Once an SWT application begins running, its Display class sorts through this queue using its readAndDispatch() method and msg field, which acts as a handle to the underlying OS message queue.
2. If it finds anything relevant, it sends the event to its top-level Shell object, which determines which widget should receive the event.
3. The Shell then sends the event to the widget that the user acted on, which transfers this information to an associated interface called a listener.
4. One of the listener’s methods performs the necessary processing or invokes another method to handle the user’s action, called an event handler.
所在包Qorg.eclipse.swt.events
typed listeners--只对某一cȝ用户事g起作用,l承TypedListenerc?br />typed events--与此cȝ定动作相关的事gQ承TypedEventc?br />
可通过add...Listener()method with the typed listener as the argument来将listener附加到widget?br />
完整的typed events和listeners列表Q如下:
TypedEventcd含了一些member field,他们提供与事件发生相关的一些信息,q些信息可以在event handler中用来获得与环境相关的信息。下图ؓl承自TypedEvent及EventObjectcȝfields:
除此之外Q很多的eventc还有其他用来提供更多用户动作信息的fields,如MouseEventcȝbutton field
要将listener加入到code中,有两个主要的ҎQ?br />W一个是在component的add...Listener()中创Z个匿名接口,q样可以使listener的作用域仅限于此component,CZ代码如下Q?br />Button button = new Button(shell, SWT.PUSH | SWT.CENTER);//创徏了一个buttonQƈ其加入到shell?br />button.addMouseListener(new MouseListener() //创徏了一个匿名MouseListener接口Qƈ其与button兌
{
public void mouseDown(MouseEvent e)
{
clkdwnEventHandler();
}
public void mouseUp(MouseEvent e)
{
clkupEventHandler();
}
public void mouseDoubleClick(MouseEvent e)
{
dblclkEventHandler(); //此接口中必须被实现的三个Ҏ。一旦鼠标按下,攑ּ或双击,׃有一个MouseEvent被发送到q三个方法中的一个,然后Q此Ҏ再调用相兌的event-handlingҎQ即下文中的三个Q?/font>
}
});
static void dblclkEventHandler()
{
System.out.println("Double click.");
}
static void clkdwnEventHandler()
{
System.out.println("Click - down.");
}
static void clkupEventHandler()
{
System.out.println("Click - up.");//event-handlers通过发送message到console来完成事件处?/font>
}
上一cL法的~点是此listener仅限于此component内,而第二种Ҏ便可解决q种问题--独立的声明一个承MouseListener的接口,CZ代码如下Q?br />Button button = new Button(shell, SWT.PUSH | SWT.CENTER);
button.addMouseListener(ExampleMouseListener);
MouseListener ExampleMouseListener = new MouseListener()
{
public void mouseDoubleClick(MouseEvent e)
{
System.out.println("Double click.");
}
public void mouseDown(MouseEvent e)
{
System.out.println("Click - down.");
}
public void mouseUp(MouseEvent e)
{
System.out.println("Click - up.");
}
};
使用MouseListener的缺点就是哪怕你只关心鼠标双MӞ却仍要声明其接口中所包含的所有方法?/font>
Adapter是承了Listener接口q提供了所有requiredҎ的实现的abstractcR也是说如果你使用adapter而不是listener的话Q你只需要写你感兴趣的方?br />
只有那些listener有多个成员方法的event才有adapter,其完整列表见下图Q?br />
adapter同样是通过add...Listener()Ҏ来创建的Q与listenercMQ同样也可通过匿名cd本地cMU方法,下例为匿名类ҎQ?br />button.addMouseListener(new MouseAdapter()
{
public void mouseDoubleClick(MouseEvent e)
{
dblclkEventHandler();
}
)};
static void dblclkEventHandler()
{
System.out.println("Double click.");
}
M时候只要key被按下,׃创徏KeyEventQ它有两个子c:TraverseEvent 和VerifyEvent.
TraverseEvent--当按下arrow key或tab key来focus on text widget?br />VerifyEvent--fires when the user enters text that the program needs to check before taking further action.
除了l承自TypedEvent和EventObject的field,KeyEventq包括三个member field来提供那些与触发事g的key相关的信息,具体如下Q?br />character--代表被按下key的char
stateMask--Returns an integer representing the state of the keyboard modifier keys.By examining this integer, a program can determine whether any of the Alt, Ctrl, Shift, and Command keys are currently pressed.
keyCode--Provides the SWT public constant corresponding to the typed key. KeyCode列表Q见下图Q?br />
TraverseEvent中有两个fields:
1. doit--q回布尔|若ؓ真则允许在各个component间切换focus,若ؓ假则不允许切换focus
2. detail--It’s an integer that represents the identity of the key that caused the event. For example, if the user presses the Tab key to switch to a new component, the detail field will contain the SWT constant TRAVERSE_TAB_NEXT.
每个cd的Control对于所l的traversal key都有不同的默认behaviorQ如果设doit为trueQ则override了其默认的设|?br />
VerifyEvent的field:
1.start和end--讑֮了输入的范围
2.text--contains the input String under examination.
3.doit--Having looked at the user’s text, you set the boolean doit field to allow (TRUE) or disallow (FALSE) the action.
更灵z,但不安全Q不推荐使用?br />当一个代表着非类型化监听器的监听器类和GUI的某一lg相联pLQ它p接受该组件所能发送的McM件。因此,你需要操控这由EventcM表的捕获的全部事Ӟ军_用户执行的那个动作。然后,正确的事件处理方法就被调用?br />
不是被包含在org.eclipse.swt.events包中Q而是被包含在org.eclipse.swt.widgets包中?br />
代码CZ如下Q?br />Listener listener = new Listener ()
{
public void handleEvent (Event event)
{
switch (event.type)
{
case SWT.KeyDown:
if (event.character == 'b')
System.out.println("Key"+event.character);
break;
case SWT.MouseDown:
if (event.button == 3)
System.out.println("Right click");
break;
case SWT.MouseDoubleClick:
System.out.println("Double click");
break;
}
}
};
Button button = new Button(shell, SWT.CENTER);
button.addListener(SWT.KeyDown, listener);
button.addListener(SWT.MouseDown, listener);
button.addListener(SWT.MouseDoubleClick, listener);
Eventcd含了所有typed event中的所有field,此外q有一个type fieldQ其所有的值列表如下:
getChildren()
lists the children of a Composite as an array of Control objects.
getLayout()、setLayout(Layout)
处理layout对象
getTabList()、setTabList(Control[])
指定widgets在Composite中的Tab序Q按键盘tab键的切换序Q?br />
CompositecLScrollablecȝ直接子类Q这是说SWT/JFace中的所有Composite对象都有Scrollbars.所有的Scrollable对象都可使用如下ҎQ?br />getClientArea()?computeTrim(int, int,int, int)
trim--Composite的不可编辑区域,如title bars, scrollbars, 或status bars{?
client area--那些可编辑,使用的区?br />getClientArea()--Returns the available display area of a Scrollable object
computeTrim(int,int,int,int)--Returns the necessary dimensions of the Composite for the desired client area
getHorizontalBar()、getVerticalBar()
Returns the horizontal/vertical ScrollBar object
Control, Scrollable, and Composite的关p,如下?br />
Composite子类中最单的一个,自n不执行Q何动作,仅仅是将一l子widgets用矩形边框v来,此边框类g之前提到的分隔符Q同样也提供SWT.SHADOW_IN, SWT.SHADOW_OUT, SWT.SHADOW_NONE风格Q还可以通过选择SWT.SHADOW_ETCHED_IN or SWT.SHADOW_ETCHED_OUT来客制化阴媄效果?br />
可以通过setText()Ҏ来设定它的label
与许多Widgets子类一PGroupcM可被l承?/font>
可以在子widgets之间创徏可移动的分界Q此分界UCؓSash.Sashcd以在org.eclipse.swt.widgets包中扑ֈQ而SashForms却存在于org.eclipse.swt.custom包中?br />
SWT.HORIZONTAL和SWT.VERTICAL--用来讑֮Sash的方?br />setOrientation()--用来讑֮Sash的方?br />getMaximizedControl()--returns the Control object that has been expanded the most.
getWeights()--returns an int array containing the weight of each of the SashForm’s children.uses an int array to specify weights for each of the widgets in the Composite.
creating and populating a TabFolder的四个步骤:
1. 创徏一个TabFolder实例
2. 为每个页面构Z个TabItem对象
3. 用setText()Ҏ来设定tab的label
4. setControl()--兌一个controlQ当它的tab被选中Ӟ昄此control
TabFoldercL供了一些用来获得TabItems信息的方法,如下Q?br />getItemCount()
q回此TabFolder所包含的TabItems?br />getItems()
q回TabItems对象的数l?br />getSelection()
定user选择了哪个TabItem
setSelection()
Makes this decision from within the application
Buttoncȝ默认风格?br />SWT.FLAT
与SWT.UP, SWT.DOWN, SWT.LEFT, and SWT.RIGHTl合Q也可用SWT.FLAT
cM于SWT.PUSHQ但是按下后会保持按下状态。可通过setSelection(boolean)Ҏ来改变其状态。接下去介绍的check按钮和radio按钮也shareq个功能
用数l来实现,如下Q?br />Button[] checks = new Button[2];
checks[0] = new Button(shell, SWT.CHECK);
checks[0].setText("Choice 1");
checks[0].setLocation(10,5);
checks[0].pack();
checks[1] = new Button(shell, SWT.CHECK);
checks[1].setText("Choice 2");
checks[1].setLocation(10,30);
checks[1].pack();
用数l来实现,如下Q?/font>
Button[] radios = new Button[3];
radios[0] = new Button(shell, SWT.RADIO);
radios[0].setSelected(true);
radios[0].setText("Choice 1");
radios[0].setLocation(10,5);
radios[0].pack();
radios[1] = new Button(shell, SWT.RADIO);
radios[1].setText("Choice 2");
radios[1].setLocation(10,30);
radios[1].pack();
radios[2] = new Button(shell, SWT.RADIO);
radios[2].setText("Choice 3");
radios[2].setLocation(10,55);
radios[2].pack();
for (int i=0; i<radios.length; i++)
if (radios[i].getSelected())
System.out.println(i);
通过RadioGroupFieldEditorsradio buttonsl合在一?
RadioGroupFieldEditor rgfe = new RadioGroupFieldEditor(
"UserChoice", "Choose an option:", 1,
new String[][] {{"Choice1", "ch1"},
{"Choice2", "ch2"},
{"Choice3", "ch3"}},
shell, true);
其中的各个参数含义如下—?.name for the type of value returned by the editor.2.group label.3.列数?.creates a set of option names with their associated values.In this manner, the RadioGroupFieldEditor can display a series of radio buttons without allocating Button objects.5.editor加至Shell对象?.specifies whether the radio buttons should be incorporated in a Group object.
在SWT/JFace?container widgets是由CompositecL提供的?/font>
寚w方式QSWT.CENTER,SWT.LEFT, and SWT.RIGHT.
分隔W:SWT.SEPARATOR;SWT.VERTICAL, SWT.HORIZONTAL;SWT.SHADOW_IN, SWT.SHADOW_OUT, and SWT.SHADOW_NONE.
是所有widget的父cRؓ抽象c,而且Eclipse.org也强烈反对去l承它,因此你既不能l承他,也不能直接用它
WidgetcM的重要方法,如下Q?/font>
ControlcM的对象在OS中有一个直接的副本Q你可以通过cȝhandle field来直接access.然而SWTq提供了一些在ControlcM外的widgets,如下所C:
Controlcȝ两类ҎQ?/font>
与SWT widgets一起工作的JFacecdUCؓmodel-based adapters [或helper classes].q些adapter可以分ؓ4c:
1.Viewers
GUIlg中的信息与外观分?[与SWT不同]
2.Actions and contributions
化了事g的处理,用户命令的反应与引发反应的事g分离
3.Image and font registries
注册机制Q?span id="BlogViewId">资源可以被按需分配和释?/span>
4.Dialogs and wizards
信息框、错误框、进度框与向导框{?/font>
package com.swtjface.Ch2;
import org.eclipse.jface.window.*;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
public class HelloSWT_JFace extends ApplicationWindow {
public HelloSWT_JFace() {
super(null); //1.Window allocation
}
protected Control createContents(Composite parent) {
Text helloText = new Text(parent, SWT.CENTER);
helloText.setText("Hello SWT and JFace!");
parent.pack();
return parent; //2.Window presentation
/*处理H口的设?׃ApplicationWindow的可视部分不能被直接accessQ此Ҏq同一个Composite来控制GUI的显C,此container对象[Composite]是所有被加入应用E序的GUIlg的父?/font>*/
}
public static void main(String[] args) {
HelloSWT_JFace awin = new HelloSWT_JFace();
awin.setBlockOnOpen(true);
awin.open();
Display.getCurrent().dispose(); //3.Window operation
/*负责GUI的实际运作。在分派好ApplicationWindow的资源之后,mainҎ使窗口显C,当setBlockOnOpen()Ҏ以一个true参数被调用的时候,H口关闭。然后ApplicationWindow的open()Ҏ被调用,ҎcreateContent()Ҏ所q回的Composite来显C窗口。然后程序通过dispose()Ҏ释放GUI的Display实例.因ؓ此程序中的所有widget都是display的childQ所以一旦释放DisplayQ所有的widget都被释放*/
}
}
SWTGUI的外观和操作都放在它的Shellc里Q而SWT/JFace却将两者分d来了Q其中外观由createContents()Ҏ内的Compsite来控Ӟ而操作部分大体上是通过ApplicationWindowcȝ实例来实现的?/font>
SWT/JFace同样需要一个单独的Display实例Q但是只要ApplicationWindow通过一个null参数来构建,那么׃创徏它自qShell。参阅下?br />
ApplicationWindow在Shell的基上提供了更多的途径来设计窗口,其相x法如下:
addMenuBar()
Configures the window with a top-level menu
addToolBar()
Adds a toolbar beneath the main menu
addStatusLine()
Creates a status area at the bottom of the window
setStatus(String)
Displays a message in the status area
getSeparator()
Returns the line separating the menu from the window
setDefaultImage(Image)
Displays an image when the application has no shell
setExceptionHandler(IExceptionHandlerQ?/u>
Configures the application to handle exceptions according to the specified interface
package com.swtjface.Ch2;
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
public class HelloSWT {
public static void main (String [] args) {
Display display = new Display();
Shell shell = new Shell(display); //1.Allocation and initialization?br />/*生成一?font size="2">Display?/font>Shellcȝ实例Q?span id="BlogViewId">GUI获取底层q_的资源ƈ开辟了一个主H口?/
Text helloText = new Text(shell, SWT.CENTER);
helloText.setText("Hello SWT!");
helloText.pack();//2.Adding widgets to the shell
/*
?/font>
Shell
上加入一个文本小部g。The code in this section also sets the parameters for these widgets, containers, and events to make sure they look and act as required.其中pack()Ҏ是tell the Shell and Text components to use only as much space as they need.*/
shell.pack();
shell.open();
while (!shell.isDisposed()){
if (!display.readAndDispatch()) display.sleep();
}
display.dispose(); //3.GUI operation
/*一旦Shell的open()Ҏ被调?应用E序的主H口和其子部仉会被呈现。只要Shell保持在打开状态,Display实例׃通过它的readAndDispatch()Ҏ来追t?span id="BlogViewId">在操作系l事仉列中的相关用户事件。当H口关闭Ӟ?/font>Display对象Q包?/font>Shell以及其子部g{)相联pȝ资源全部释?/font>*/
}
}
Display cdƈ不是可见的,但它负责监管着 GUI 的资源ƈ理着和操作系l的通信?span id="BlogViewId">它不光要x着它自qH口是如何显C、移动和重画的,q同时要保诸如鼠标点击、键盘敲ȝ事g送达widgetsq去处理它们?/font>
是Q?/font>
SWT
?/font>
JFace
应用E序的承载着Q无Z是用
SWT/JFace
开发或是单?/font>
SWT
开发,你必d你的E序中包含这个类的一个实例?br />
Display
cȝ主要d是负责你的代码重?/span>
SWT
?/span>
JFace
命o译成底层的命o来调取操作系l?/font>
q一q程包含了两部分Q?/font>
1.Display
对象构徏一个代表着操作pȝq_?/font>
OS
cȝ实例Q这个类通过一pd被称之ؓnative methods的特D?/font>
Java
E序提供了接触计机底层资源的途径?.
q个
Display
对象使用q些Ҏ来直接指令操作系lƈ向应用程序传辄户动作?br />
if any features in your operating system aren’t incorporated into SWT, you can use the Java Native Interface to add them yourself.All it requires is a native Java method in the SWT package and a C function in the native graphics library that calls the operating system.
1.Display()--Allocates platform resources and creates a Display object
must be used in any SWT-based GUI.它生一个Displaycȝ实例q将其和GUI相联p?/font>
2.getCurrent()--Returns the user-interface thread
must be used in any SWT-based GUI.它返回一个应用程序的ȝE,用户界面U程,通常和dispose()一起用来l束Display的操作?/font>
3.readAndDispatch()--Display object interprets events and passes them to receiver
enable the application to receive notifications from the operating system whenever the user takes an action associated with the GUI.
accesses the operating system’s event queue and determines whether any of the user’s actions are related to the GUI.
Using this method, the HelloSWT class knows whether the user has decided to dispose of the Shell. If so, the method returns TRUE, and the application ends. Otherwise, the Display object invokes its sleep() method, and the application continues waiting.
4.sleep()--Display object waits for events
enable the application to receive notifications from the operating system whenever the user takes an action associated with the GUI.
The Shell class accesses the operating system through the OS class to an extent, but only to keep track of opening, activating, maximizing, minimizing, and closing the main window.
The main function of the Shell class is to provide a common connection point for the containers, widgets, and events that need to be integrated into the GUI. Shell serves as the parent class to these components.
attached to the Display的shell--top-level shells
NOT directly attached to the Display instance的shell--secondary shell
在你?/font>GUI之内Q你可以讑֮shell或其他小部g的风格参数|若是多个值则可以用?/font>|?/font>相连.除了提到的属性,默认为?span id="BlogViewId">SHELL_TRIM”?br />
SHELL_TRIM--有一个标题栏(SWT.TITLE)和用户可以最化SWT.MIN)、最大化(SWT.MAX)、改变尺?/font>(SWT.RESIZE)和关?/font>(SWT.CLOSE)
DIALOG_TRIM--有一个标题栏、一个活动区的边?/font>(SWT.BORDER)和被关闭的能?/font>
你还可以定shell的Ş态,以限定用户修?/font>shell的modality,如A modal dialog box不能被移动或是改变尺寸,只可以用给予的按钮关闭或是取消?/font>
NOT every platform can render these properties in GUI components.