前言:哈哈哈,最近清理了下群里的人。主要是想整顿下风气,希望大家能活跃一点 ,不过好像效果不是很好。还好我做了两手准备,反正留言的是想留下来的,而且有空的。接下来我想和几个人一起做几个小程序出来,毕竟现在不是一个人关门早车有什么前途的年代呀……今天在学校有空,又翻译了半章。
by Shantha Ramachandran
Department of Computer Science, Uniersity of Manitoba, Winnipeg, Canada
Overview:
接下来的文档中,我们将介绍一些高级的SWT widgets。
Tables:
下面的代码会添加一个table控件到你的shell上:
Talble table1= new Table(shell, SWT.BORDER);
它支持的样式有:BORDER,H_SCROLL,V_SCROLL,SINGLE,MULTI,CHECK(这个样式在第一列创建一个check box列),FULL_SELECTION和HIDE_SELECTION。
你可以为table设置两个选项。你可以决定是否显示table内的分隔线。你还可以决定是否突出显示列名。这两个属性默认都是关闭的。接下来的代码会教你设置这些属性:
table1.setLinesVisible(true);
table1.setHeaderVisible(true);
好了,table已经创建好了,但是默认的它只有一列。如果你想添加了内容到这个table里,也只有第一列内的内容会显示出来。为了显示出你想要的效果,你就必须定义TableColumns。
TalbeColumns:
下面代码添加表的列:
TableColumn name = new TableColumn(table1,SWT.LEFT);
它支持的样式有:LEFT,RIGHT和CENTER。
你同时也应该设置它的宽度以及列名(如果你想显示列名):
name.setText("Name");
name.setWidth(50);
为你的表建立了列,现在你就可以往里面添加东西了。这就需要用到TableItem。
TableItem:
用下面的代码来向表添加内容:
TableItem item1 = new TableItem(table1, SWT.NONE);
它没有可用的风格,所以你可以放置一个SWT.NONE,它表示0。
你可以用setText()方法为这个item设定一个文本:
item1.setText(new String[] {"Sarah","15","390 Sussex Ave"});
这段代码会建立一个你自己定义内容(文本内容)的TableItem。如果你想要一次定义其中某一个的区域,那么你可以使用setText(int, string)方法。这个方法把文本放在指定的记录中。
当建立好TableColumn和TableItem后,你的Table就比较“丰满”了。接下来我们来看个用三个table的例子,然后看下它用了那些不同的风格样式。
第一个table有一个边框,大小合适的列以及不同的水平对其方式:


















第二个Table有列checkbox。我们可以通过代码设置checked的状态。里面没有网格线,但是它的列名是突出显示的。这个表格的例子还为表格内其中一行设置了背景颜色:
table2.setBounds( 10 , 80 , 270 , 80 );
table2.setHeaderVisible( true );
TableColumn fruit = new TableColumn(table2,SWT.LEFT);
fruit.setText( " Fruit " );
fruit.setWidth( 100 );
TableColumn colour = new TableColumn(table2,SWT.LEFT);
colour.setText( " Colour " );
colour.setWidth( 170 );
TableItem fruit1 = new TableItem(table2,SWT.NONE);
fruit1.setText( 0 , " Apple " );
fruit1.setText( 1 , " Red " );
fruit1.setChecked( true );
TableItem fruit2 = new TableItem(table2,SWT.NONE);
fruit2.setText( new String[] { " Kiwi " , " Green " });
fruit2.setBackground( new Color(display, 255 , 0 , 0 ));
TableItem fruit3 = new TableItem(table2,SWT.NONE);
fruit3.setText( new String[] { " Banana " , " Yellow " });
最后一个表格的例子用了FULL_SELECTION的样式。它意味着当你选择一个表格的单元格时高亮显示这一整行而不单单显示第一列区域。第一列是大小可变的,也就是说你可以随意用鼠标拖拽它的大小。注意,三列字段都有自己的对其方式:
table3.setLinesVisible( true );
table3.setBounds( 10 , 180 , 270 , 80 );
TableColumn first = new TableColumn(table3,SWT.LEFT);
first.setResizable( true );
first.setText( " First " );
first.setWidth( 80 );
TableColumn second = new TableColumn(table3,SWT.CENTER);
second.setText( " Second " );
second.setWidth( 80 );
TableColumn third = new TableColumn(table3,SWT.RIGHT);
third.setText( " Third " );
third.setWidth( 80 );
String[] numbers = new String[] { " One " , " Two " , " Three " };
TableItem firstItem = new TableItem(table3,SWT.NONE);
firstItem.setText(numbers);
TableItem secondItem = new TableItem(table3,SWT.NONE);
secondItem.setText(numbers);
TableItem thirdItem = new TableItem(table3,SWT.NONE);
thirdItem.setText(numbers);
TableItem fourthItem = new TableItem(table3,SWT.NONE);
fourthItem.setText(numbers);
table3.select( 1 );
下面是代码合并后的效果图:
TabFolder:
用以下代码添加一个标签页控件(tab folder)到shell:
TabFolder tabFolder1 = new TabFolder(shell,SWT.NONE);
以下代码创建一个TabItem:
TabItem item1 = new TabItem(tabFolder1,SWT.NONE);
TabItem没有相对应的样式。创建一个标签页的一个内容条目必须遵循两个重要的步骤。首先,如果你想让这个标签页显示一个Label,那么你需要用setText()方法去完成。然后为了装上这个刚定义的TabItem,你必须用setControl()方法设置它含有哪个控件:
item1.setText("Buttons");
item1.setControl(buttonComp);
就像你在后面的例子中看到的一样,buttonComp是一个Composite。之后你可以添加多种控件到这个composite中。下面是这个例子的具体代码:
tabFolder1.setBounds( 10 , 10 , 270 , 250);
// Set up the button tab
Composite buttonComp = new Composite(tabFolder1,SWT.NONE);
Button button1 = new Button(buttonComp,SWT.PUSH);
button1.setSize( 100 , 100);
button1.setText( " Hello ");
button1.setLocation( 0 , 0);
Button button2 = new Button(buttonComp,SWT.ARROW);
button2.setBounds( 150 , 0 , 50 , 50);
TabItem item1 = new TabItem(tabFolder1,SWT.NONE);
item1.setText( " Buttons ");
item1.setControl(buttonComp);
// Set up the label tab
Composite labelComp = new Composite(tabFolder1,SWT.NONE);
Label label1 = new Label(labelComp,SWT.NONE);
label1.setText( " Here are some labels for your viewing pleasure ");
label1.setBounds( 0 , 0 , 250 , 20);
Label label2 = new Label(labelComp,SWT.NONE);
label2.setText( " A label is a fine fingered fiend ");
label2.setBounds( 0 , 40 , 200 , 20);
TabItem item2 = new TabItem(tabFolder1,SWT.NONE);
item2.setText( " Labels ");
item2.setControl(labelComp);
这个例子创建了一个有两个页面的TabFolder,一个用来放按钮,另一个用来放Lable。当窗口初始化显示后,它是下面图示的样子:
如果你单击Labels的标签(tab),那么标签页就转换到Labels的内容下,看上去像这样:
Slider, Scale and Progress Bar:
Slider、Scale和Progress Bar是一些很相似的控件。不过他们各自有不同的方法来运行。我们暂时大致了解下这个三个widget,之后会用例子分别看下这些小控件。先由Slider和Scale开始,因为它们两个有很多相同的功能。
以下代码创建一个Slider:
Slider slider1 = new Slider(shell, SWT.HORIZONTAL);
创建一个Scale:
Scale scale1 = new Scale(shell, SWT.HORIZONTAL);
它们两个能设置的样式有:BORDER,HORIZONTAL和VERTICAL。
你可以用setMinimum()和setMaximum()方法来设置Slider或者Scale最小值和最大值。
slider1.setMaximum(100);
slider1.setMinimum(0);
你可能像设置Slider或者Scale的拖动的位置。下面的代码表示Slider的滑块在中间的情况。
slider1.setSelection(50);
同样,你还可以设置滑块的尺寸。这个尺寸和你设置Slider的最大值和最小值有关。举个例子,如果你设置最小值为0,最大值为100,然后设置滑块的尺寸为30,那么这个滑块将会占整个Slider的三分之一大小。
slider1.setThumb(30);
对于Scale,你可以设置每格的增量。这取决于你放置的刻度的大小。举个例子,如果你设置Scale的最小值为0,最大值为500,然后设置增量为50,那表示整个Scale上有10个刻度。它也取决于Scale的最大值和最小值。
接下来的例子会把两个widget放在一起顺便讨论它们的方法(methods):
slider1.setBounds( 0 , 0 , 200 , 20);
slider1.setSelection( 50);
slider1.setMaximum( 100);
slider1.setMinimum( 0);
slider1.setThumb( 30);
Scale scale1 = new Scale(shell, SWT.HORIZONTAL);
scale1.setBounds( 0 , 40 , 200 , 40);
scale1.setMinimum( 0);
scale1.setMaximum( 500);
scale1.setSelection( 100);
scale1.setPageIncrement( 50 );
下面是这段代码的效果图:
接下来我们来看以下Progress Bar。
以下代码创建一个Progress Bar:
ProgressBar progressBar1 = new ProgressBar(shell,SWT.HORIZONTAL);
它可以设置的样式有:BORDER,VERTICAL和HORIZONTAL(就和Slider和Scale一样),不过你还能用SMOOTH样式,它使得进度指示器(progress indicator)变得更加平滑。
对于一个进度条来说,你只能设置它的最小值、最大值以及进度指示位置。进度位置是基于最小值和最大值来设置的(你不能大于最大值或者小于最小值了)。不像Scale或者Slider,你不能改变进度条的宽度,或者进度记号(progress marker)。
下列代码本别对这些方法举例:
progressBar1.setMinimum( 0);
progressBar1.setMaximum( 100);
progressBar1.setSelection( 30);
progressBar1.setBounds( 10 , 10 , 250 , 20 );
下面是代码产生的窗口效果:
Menus and MenuItems:
我们来看两个菜单的例子。第一个比较基础,只是创建了一个带有选项的普通菜单,并且添加了选择事件。另一个比较大的例子演示了菜单的一些更加复杂的使用,包括子菜单,加速键,mnemoics(不好翻,暂且放这里,下面有介绍,相信大家一看就懂什么意思了:p)还有添加了相应的事件以及一些可用的不同类型的菜单选项(内容)。
用Menu和MenuItem控件可以设置菜单。
以下代码在shell的顶部创建了一个菜单。
Menu menu = new Menu(shell, SWT.BAR);
shell.setMenuBar(menu);
它的样式必须为SWT.BAR。
然后,我们要加点东西到这个菜单栏中去。
MenuItem file = new MenuItem(menu, SWT.CASCADE);
file.setText("File");
上面的代码会在菜单栏上创建一个名为“File”的选项。如果你就运行这几行代码,你将会看到一个只显示File字样的菜单栏的窗口。而且你按下这个选项也不会发生什么事情。要先保证它(MenuItem)的样式是SWT.CASCADE否则你不能放一个下拉菜单上去。
现在我们就来演示当你单击File选项时如何显示一个下拉菜单。
Menu filemenu = new Menu(shell, SWT.DROP_DOWN);
file.setMenu(filemenu);
这个菜单的样式必须为SWT.DROP_DOWN,而且要依附到正确的MenuItem上。
最后,我们可以添加一个MenuItem到外面的“File”菜单上,并使它有交互的效果。
MenuItem actionItem = new MenuItem(filemenu, SWT.PUSH);
actionItem.setText("Action");
通过以下代码,为这个选项添加一个listener:
public void handleEvent(Event e) {
System.out.println( " Action performed! " );
}
});
当“Action”选项被按下时,控制台上会输出“Action performed!”。重复这些步骤,你就可以为你的程序添加一些有用的普通菜单了。
最后这些菜单会显示成这个样子:
我们现在开始弄点长点的例子。首先要考虑的就是MenuItem支持的其他除了SWT.PUSH的样式。包括CHECK,RADIO,SEPARATOR和CASCADE。第一个是一个checkbox(检查栏)选项,第二个是一个单选按钮选项。SEPARATOR是用来分隔其它选项的水平分隔线,它是不可选中的。下面的代码演示了如何使用CHECK,SEPARATOR和RADIO选项。它会依次创建一条分隔线,一个检查栏样式的菜单选项,最后是一个单选风格的菜单选项。
final MenuItem radioItem = new MenuItem(filemenu, SWT.RADIO);
radioItem.setText( " Radio " );
final MenuItem checkItem = new MenuItem(filemenu, SWT.CHECK);
checkItem.setText( " Check " );
接下来的几行为Check和Radio选项添加listener(在控制台输出它们当前的值-true或者false)。
public void handleEvent(Event e) {
System.out.println( " Radio item toggled to: " +
radioItem.getSelection());
}
});
checkItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
System.out.println( " Check item toggled to: " +
checkItem.getSelection());
}
});
接下来我们创建一个子菜单,就和创建菜单到菜单栏很相似。我们用SWT.CASCADE样式创建一个新的MenuItem,然后创建一个新的菜单并依附到这个下拉菜单上去。我们可以调用setMenu()方法来添加这个新建的菜单。
cascadeItem.setText( " Cascade " );
Menu submenu = new Menu(shell, SWT.DROP_DOWN);
cascadeItem.setMenu(submenu);
下面的几行代码添加一个菜单选项到上面的子菜单中。新的选项叫做“SubAction”。注意,在setText()方法中,在S之前有一个&的记号。这样设置后,当子菜单显示时,只要按下键盘上的S键就会选中这个选项,就像用鼠标选中一样(就像有记忆效果一样,这里叫做mnemonic)。调用中接下来在该选项(SubAction)上设置了一个加速键(setAccelerator()),当按下Control-S的联合按钮时就直接执行SubAction命令,无论是否点开了这个下拉菜单。
subactionItem.setText( " &SubAction Ctrl+S " );
subactionItem.setAccelerator(SWT.CTRL + ' S ' );
我们在这个子菜单上添加一个额外的选项用来演示启用和屏蔽MenuItem的效果。我们添加一个检查栏,它会启动和屏蔽SubAction这个选项:
enableItem.setText( " Enable SubAction " );
这里我们添加一个之前从来没有用到过的listener:MenuListener,它会在控制台告诉我们按钮的状态:
public void menuShown(MenuEvent e) {
System.out.println( " SubMenu shown " );
}
public void menuHidden(MenuEvent e) {
System.out.println( " SubMenu hidden " );
}
});
下面来用另一个检查栏选项来设置启动还是屏蔽菜单选项。第一行首先使得SubAction一开始就被屏蔽,它的文本的颜色是暗的。当屏蔽掉了后,你就不能选择该选项,并且它上面的加速键也失灵了。后面的代码添加了一个listener,它依据“Enable SubAction”这个检查栏选项是否被按下来屏蔽或者启用SubAction这个MenuItem选项。
enableItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
System.out.println( " Toggling "Enable SubAction" to " +
enableItem.getSelection());
subactionItem.setEnabled(enableItem.getSelection());
}
});
添加一个普通的listener:
public void widgetSelected(SelectionEvent e) {
System.out.println( " SubAction performed! " );
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
另一个有趣的listener是ArmListener。当一个菜单选项因为鼠标或者键盘变成高亮(其实也就是指针或者用方向键移到该选项上)但是没有选中(没有按下左键或者回车键)时调用内部的widgetArmed(ArmEvent e)方法。
public void widgetArmed(ArmEvent e) {
System.out.println( " SubAction armed! " );
}
});
最后的listener类型是HelpListener。当按下F1/Help键时激活HelpListener。它可能会通过各种各样的选项提供很多有用的帮助。
public void helpRequested(HelpEvent e) {
System.out.println( " Help requested on SubAction " );
}
});
当按下Enable SubAction选项时将会激活SubAction。按Ctrl+S将执行SubAction对应的程序,但是只有当Enable SubAction是选中的情况下才有用。当listener激活时,它们会向控制台打印信息。
Menu和MenuItem还有很多其他可用的小工具,我们这里尽量介绍其中多数的有用的一部分。下面让我们来简要得看一下简单的pop-up菜单。
Popup Menus:
Pop-up菜单是很有用的context-sensitive菜单,它可以在屏幕上不同的区域出现,它远比让用户去菜单栏找寻他们想要的选项然后按下要方便快速地多!在一个Composite上用鼠标右键单击就会在鼠标指针边上浮现一个pop-up菜单,它上面以列表的形式让用户选择一些常用的菜单。在下面的演示中,我们在shell的composite中创建了一个按钮。然后我们创建了两个pop-up菜单,然后一个在这个按钮上响应,另一个在composite和shell中得到响应。
我们首先创建一个SWT.POP_UP风格的菜单,然后添加一些选项进去,然后用一个listener来捕捉选择的事件。下面这个是用在shell和composite响应的:
MenuItem actionItem = new MenuItem(popupmenu, SWT.PUSH);
actionItem.setText( " Other Action " );
actionItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
System.out.println( " Other Action performed! " );
}
});
我们重复上面的过程,下面的代码会和按钮联系起来:
MenuItem buttonItem = new MenuItem(popupmenu2, SWT.PUSH);
buttonItem.setText( " Button Action " );
buttonItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
System.out.println( " Button Action performed! " );
}
});
然后我们创建一个composite和一个button。
c1.setSize ( 100 , 100 );
c1.setLocation( 25 , 25 );
Button b = new Button(c1, SWT.PUSH);
b.setText( " Button " );
b.setSize( 50 , 50 );
b.setLocation( 25 , 25 );
最后,我们为相应的控件设置pop-up菜单。
c1.setMenu (popupmenu);
shell.setMenu (popupmenu);
现在我们可以运行代码,然后在按钮上点右键,它会显示一个菜单,如果我们在composite或者shell上点右键我们会看到一个带不同菜单选项的菜单显示在屏幕上。下面的图例是在按钮上点击右键后的结果。
虽然这是一个简单的例子,但是弹出(pop-up)菜单可以和子菜单、单选、listener等一起使得早前我们写的Menu bar的例子更加复杂。(这就看你的需要的了咯~)
先翻到这里吧,我发现我已经有点思维混乱了,翻得也是牛头不对马嘴,休息下下……