SWT高級主題(Standard Widget Toolkit)第一部分
在SWT基礎中,我們簡要的瞭解了SWT的產生背景,開發SWT應用程序的基本要求以及基本的SWT組件以及部分事件監聽器。本部分內容將介紹一些高級的組件,佈局管理器等高級主題。
高級組件:
Tables:Table組件用於顯示圖片或者字符串的列表,並且在被選擇的時候可以彈出提示。
Table table1 = new Table(shell, SWT.BORDER);
可選的樣式包括:BORDER,H_SCROLL,V_SCROLL,SINGLE,MULTI,CHECK(在第一列產生checkbox列),FULL_SELECTION和HIDE_SELECTION。VITURAL創建的table的TableItems可以很大的提高性能。
可以設置table中的線以及table的header是否可見,默認的設置都是false。雖然這個類也是Composite的子類,但是爲其添加Control,或者爲其設置Layout是沒有意義的,除非實現像cell編輯器一樣的東西。
Table創建完成後,默認只有一列,如果要追加內容,只有每行的第一列會被顯示,爲了顯示所有的field,需要定義TableColumns。
TableColumn:將TableColumn追加到Table的方法如下:
TableColumn name = new TableColumn(table, SWT.LEFT);
可選的樣式包括LEFT,RIGHT,CENTER.
同時至少要設置column的寬度,如果要顯示header的話,還需要設置名字。
name.setText("Name");
name.setWidth(50);
創建完Table的列之後,就可以添加TableItems了。
TableItem:通過下面的語句將TableItem追加到Table中。
TableItem item1 = new TableItem(table,SWT.NONE);
沒有什麼適用於TableItem的樣式,所以設置爲SWT.NONE。
可以使用item1.setText(String[])或者item1.setText(int, String)的方式來填充TableItem。如果Table的style不是FULL_SELECTION,那麼只有第一列是可選的,即鼠標選中時有反應,而其他的field是不可選擇的。
TabFolder:用於實現像筆記本一樣的功能,用戶可以選擇任意一個tab。
TabFolder tabFolder = new TabFolder(shell,SWT.NONE);
支持TabFolder的style有TOP,BOTTOM。雖然該類是Composite的子類,但是對它設置layout是沒有意義的。
可以通過以下的方式創建TabItem:
TabItem item1 = new TabItem(tabFolder,SWT.NONE);
沒有可用的樣式。創建tab item有兩個步驟,首先,創建tab上面的label,可以通過setText方法設置。然後,爲了顯示tab item,需要設置它包含的control,通過setControl方法:
item1.setText("Buttons");
item1.setControl(buttonComp);
在上面的例子中,buttonComp是一個Composite,每個tab item中只可以放一個control,所以一般來說必須是一個Composite,這樣纔可以包含其他的組件。事件處理已經內置到TabItem和TabFolder中。
TabFolder tabFolder1 = new TabFolder(shell,SWT.NONE);
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);
Slider,Scale,Progress Bar:滑塊,調節器和進度條是非常相似的控件。但是它們使用一些不同的方法來正常的工作。
Slider slider1 = new Slider(shell, SWT.HORIZONTAL);
Scale scale1 = new Scale(shell, SWT.HORIZONTAL);
適用於Slider和Scale的樣式包括:BORDER,HORIZONTAL和VERTICAL.可以通過方法設置最大值和最小值:
slider1.setMaximum(100);
slider1.setMinimum(0);
可以通過slider.setSelection(50);來確定滑塊或者標記的位置。如前所示,滑塊的左側將會位於整個區域的中間。如果是Slider的話,還可以設置滑塊的大小。slider.setThumb(30);對於Scale,可以設置頁面的增量,來確定測量條放在scale上的個數。通過使用scale.setPageIncrement(50);來進行設置。
Slider slider1 = new Slider(shell, SWT.HORIZONTAL);
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);
可以通過下面的代碼來創建一個進度條:
ProgressBar progressBar1 = new ProgressBar(shell,SWT.HORIZONTAL);
可以使用的樣式包括BORDER、VERTICAL、HORIZONTAL。也可以使用SMOOTH,返回一個平滑的bar。對於進度條來說,可以設置最大,最小值和選擇位置。選擇位置基於最小值和最大值,和slider不同,不可以設置進度條的進度提示條的寬度。
ProgressBar progressBar1 = new ProgressBar(shell,SWT.HORIZONTAL);
progressBar1.setMinimum(0);
progressBar1.setMaximum(100);
progressBar1.setSelection(30);
progressBar1.setBounds(10,10,250,20);
菜單和菜單項:菜單可以包含子菜單,快捷鍵,事件處理以及不同的菜單項。通過使用Menu和MenuItem組件來設置菜單。可以通過下面的代碼在shell的頂部創建菜單區域:
Menu menu = new Menu(shell, SWT.BAR);
shell.setMenuBar(menu);
菜單欄的樣式必須爲SWT.BAR。可用的樣式包括:BAR, DROP_DOWN, POP_UP, NO_RADIO_GROUP,LEFT_TO_RIGHT, RIGHT_TO_LEFT。
Note: Only one of BAR, DROP_DOWN and POP_UP may be specified. Only one of LEFT_TO_RIGHT or RIGHT_TO_LEFT may be specified.
下面向Menu中添加一個MenuItem。
MenuItem file = new MenuItem(menu,SWT.CASCADE);
fule.setText(“File”);
添加完成之後,可以看到在shell的頂部的菜單欄中,包含一個File菜單,點擊之後,沒有任何的反應,確保樣式是SWT.CASCADE,即級聯菜單,這樣纔會彈出下拉菜單。
接下來可以向File選項中追加菜單:
Menu fileMenu = new Menu(shell, SWT.DROP_DOWN);
file.setMenu(fileMenu);
最後,可以將菜單項添加到菜單中:
MenuItem actionItem = new MenuItem(fileMenu, SWT.PUSH);
actionItem.setText(“Action”);
至此,已經創建了一個包含可以選擇項目的文件菜單。爲了提示選項被選擇,可以爲菜單項追加事件監聽器:
actionItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
System.out.println("Action performed!");
}
});
繼續一個更復雜一些的例子,首先MenuItem的樣式不再是PUSH,可選的樣式包括CHECK,RADIO,SEPARATOR,CASCADE。分別表示複選框,單選按鈕,分隔符。
MenuItem separator = new MenuItem(filemenu, SWT.SEPARATOR);
final MenuItem radioItem = new MenuItem(filemenu, SWT.RADIO);
radioItem.setText("Radio");
final MenuItem checkItem = new MenuItem(filemenu, SWT.CHECK);
checkItem.setText("Check");
下面的代碼爲單選按鈕和複選框追加了事件監聽器:
radioItem.addListener(SWT.Selection, new Listener() {
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());
}
});
下面通過和創建菜單一樣的方式創建子菜單:
MenuItem cascadeItem = new MenuItem(filemenu, SWT.CASCADE);
cascadeItem.setText("Cascade");
Menu submenu = new Menu(shell, SWT.DROP_DOWN);
cascadeItem.setMenu(submenu);
然後爲子菜單追加菜單項,新追加的菜單項叫做SubAction。注意,在設置標題的時候,在字符S前面使用了&符號,表示助記符。當子菜單被現實的時候,可以通過按下S鍵,選擇該菜單項。然後通過setAccelerator來爲SubAction設置快捷鍵,爲CTRL+S。此時用戶可以不需要打開菜單就可以執行該操作。
final MenuItem subactionItem = new MenuItem(submenu, SWT.PUSH);
subactionItem.setText("&SubAction/tCtrl+S");
subactionItem.setAccelerator(SWT.CTRL+'S');
然後追加一個用來顯示是否啓用菜單項的子菜單選項:
final MenuItem enableItem = new MenuItem(submenu, SWT.CHECK);
enableItem.setText("Enable SubAction");
有很多可用的監聽器,下面只舉個簡單的例子,子菜單顯示和隱藏時的事件處理:
submenu.addMenuListener(new MenuListener() {
public void menuShown(MenuEvent e) {
System.out.println("SubMenu shown");
}
public void menuHidden(MenuEvent e) {
System.out.println("SubMenu hidden");
}
});
可以通過以下的方式來禁用或者啓用菜單項:
subactionItem.setEnabled(false);
enableItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
System.out.println("Toggling /"Enable SubAction/" to "
+ enableItem.getSelection());
subactionItem.setEnabled(enableItem.getSelection());
}
});
還可以直接使用SelectionListener:
subactionItem.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
System.out.println("SubAction performed!");
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
另外一個事件監聽器就是ArmListener,當菜單項被選中,高亮顯示時,但是還沒有選擇(鼠標點擊或者按下回車鍵)時,觸發該事件。
subactionItem.addArmListener(new ArmListener() {
public void widgetArmed(ArmEvent e) {
System.out.println("SubAction armed!");
}
});
還有一個監聽器就是幫助監聽器HelpListener,通過按下F1/Help鍵,HelpListener被觸發。可以用來提供幫助信息。
subactionItem.addHelpListener(new HelpListener() {
public void helpRequested(HelpEvent e) {
System.out.println("Help requested on SubAction");
}
});
彈出菜單:彈出式菜單對於屏幕不同區域的上下文菜單很有用,這樣用戶就可以不用去屏幕頂部的菜單欄去找菜單項了。通過右鍵點擊具有上下文關聯菜單的Composite,可以在鼠標邊上懸浮菜單,允許用戶選擇菜單項。
和之前一樣,創建一個菜單,將菜單的樣式設置爲SWT.POP_UP,然後爲其添加一個item,然後添加一個事件監聽器來監聽選擇時間,這就是shell和composite的菜單:
Menu popupmenu = new Menu(shell, SWT.POP_UP);
MenuItem actionItem1 = new MenuItem(popupmenu, SWT.PUSH);
actionItem1.setText("Other Action");
actionItem1.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
System.out.println("Other Action performed!");
}
});
Menu popupmenu2 = new Menu(shell, SWT.POP_UP);
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,將其添加到shell上,然後爲button,composite和shell設置彈出菜單:
Composite c1 = new Composite(shell, SWT.BORDER);
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);
b.setMenu(popupmenu2);
c1.setMenu (popupmenu);
shell.setMenu (popupmenu);
同樣,右鍵菜單可以有子菜單,單選按鈕,事件監聽器等等功能。
樹:樹結構用來顯示層狀結構的信息,例如顯示文件夾和子文件夾,類和子類等。創建樹的樣式可以是SWT.MULTI,SWT.SINGLE,SWT.CHECK. SINGLE只允許選中樹中的一個項目,MULTI可以選擇多個。同時只能指定兩者中的一個。CHECK爲樹的每個選項增加複選框。例如Eclipse使用CHECK樣式的tree來選擇將哪些文件導入/導出。
final Tree tree = new Tree(shell, SWT.MULTI | SWT.BORDER);
tree.setSize(150, 150);
tree.setLocation(5,5);
上面的代碼創建了一個簡單的沒有枝幹和葉子的樹,允許多選並且帶有邊框。通過添加TreeItem來爲樹添加內容。首先創建樹根。
TreeItem myComp = new TreeItem(tree, SWT.NONE);
myComp.setText("My Computer");
TreeItem netPlaces = new TreeItem(tree, SWT.NONE);
netPlaces.setText("My Network Places");
TreeItem myDocs = new TreeItem(tree, SWT.NONE, 1);
myDocs.setText("My Documents");
第三個參數表示TreeItem的位置。上面的代碼中,My Documents節點位於中間。
通過使用相同的構造器來創建TreeItem的子節點。
TreeItem hardDisk = new TreeItem(myComp, SWT.NONE);
hardDisk.setText("Local Disk (C:)");
TreeItem floppy = new TreeItem(myComp, SWT.NONE, 0);
floppy.setText("3.5 Floppy (A:)");
可以持續的這樣創建下去。例如爲磁盤C再創建子節點:
TreeItem progFiles = new TreeItem(hardDisk, SWT.NONE);
progFiles.setText("Program Files");
同時,還可以爲TreeItem添加圖片:
Image icon = new Image(display, "arrow.jpg");
progFiles.setImage(icon);
還可以爲樹追加事件監聽器,事件監聽器是和整個樹對象關聯在一起的。但是用SelectionListener時,getSelection()返回的是選中的樹的TreeItem的列表。還可以監聽樹的合起與打開事件:
tree.addTreeListener(new TreeListener() {
public void treeCollapsed(TreeEvent e) {
System.out.println("Tree collapsed.");
}
public void treeExpanded(TreeEvent e) {
System.out.println("Tree expanded.");
}
});
其中TreeEvent具有item屬性,表示選中的item。
如果樹的樣式爲CHECK,那麼還可以通過調用getChecked方法來判斷TreeItem是否被選中。
工具欄:工具欄可以爲經常使用的任務提供快捷方式,而不是使用複雜的菜單。工具欄上面的按鈕和標準的按鈕的樣子基本相同,只是他們以分組的方式顯示在工具欄中,並且可以同時包含文本和圖片。
final ToolBar bar = new ToolBar(shell,SWT.HORIZONTAL);
bar.setSize(380,150);
bar.setLocation(10,10);
爲了將圖片添加到一些按鈕上,必須將圖片加載。
Image icon = new Image(display,”arrow.bmp”);
接下來初始化三個Tool項目。每個都是一個簡單的壓下式按鈕。
ToolItem pushItem1 = new ToolItem(bar, SWT.PUSH);
pushItem1.setText("Push");
ToolItem pushItem2 = new ToolItem(bar, SWT.PUSH);
pushItem2.setImage(icon);
ToolItem pushItem3 = new ToolItem(bar, SWT.PUSH);
pushItem3.setText("Push");
pushItem3.setImage(icon);
上面的代碼創建三個ToolItem,其中分別包含了文字,圖片,圖片和文字。圖片位於文字上方。
還可以創建一個SEPARATOR樣式的可見分割條。
ToolItem sep = new ToolItem(bar, SWT.SEPARATOR);
同樣可以包含CHECK和RADIO的按鈕。
ToolItem checkItem = new ToolItem(bar, SWT.CHECK);
checkItem.setText("Check");
new ToolItem(bar, SWT.SEPARATOR);
ToolItem radioItem1 = new ToolItem(bar, SWT.RADIO);
radioItem1.setText("Radio 1");
ToolItem radioItem2 = new ToolItem(bar, SWT.RADIO);
radioItem2.setText("Radio 2");
new ToolItem(bar, SWT.SEPARATOR);
ToolItem radioItem3 = new ToolItem(bar, SWT.RADIO);
radioItem3.setText("Radio 3");
ToolItem radioItem4 = new ToolItem(bar, SWT.RADIO);
radioItem4.setText("Radio 4");
上面的代碼有兩處需要注意:一,單選按鈕的行爲是自動完成的,即上面的單選按鈕1和2,3和4自動編成組,即1和2只能選中一個,3和4只能選中一個。(在菜單中的這個功能必須手動編成完成)。二,一中描述的功能當前僅當兩個radio按鈕緊挨着時。
最後一種ToolItem是下拉式的按鈕。左側按鈕和標準的按鈕一樣,右側包含了一個下拉式的箭頭來提示包含下拉菜單。爲了將下拉菜單和其綁定,必須捕獲selection事件,然後使用SelectionEvent的x和y座標來決定在哪裏彈出菜單。
final ToolItem dropdown = new ToolItem(bar, SWT.DROP_DOWN);
dropdown.setText("Drop-down");
final Menu menu = new Menu(shell, SWT.POP_UP);
MenuItem choice = new MenuItem(menu, SWT.PUSH);
choice.setText("Choices");
dropdown.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if (event.detail == SWT.ARROW) {
Rectangle rect = dropdown.getBounds();
Point pt = new Point(rect.x, rect.y + rect.height);
pt = bar.toDisplay(pt);
menu.setLocation(pt.x, pt.y);
menu.setVisible(true);
}
}
});
CoolBar:CoolBar可以創建和工具欄一樣的元素,只是可以動態的由用戶擺放。例如Eclipse頂部的工具欄。可以拖放在任意的位置。類似的CoolBar還出現在Word以及IE中。
final CoolBar bar = new CoolBar(shell, SWT.BORDER);
CoolItem item1 = new CoolItem(bar, SWT.NONE);
CoolItem item2 = new CoolItem(bar, SWT.NONE);
CoolItem item3 = new CoolItem(bar, SWT.NONE);
CoolItem item4 = new CoolItem(bar, SWT.NONE, 2);
可以通過鎖定來禁止拖拽CoolItem。
bar.setWrapIndices(new int[] { 3 });
bar.setSize(300, 120);
Button button1 = new Button(bar, SWT.FLAT | SWT.BORDER);
button1.setText("Button");
button1.pack();
button1.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
bar.setLocked(!bar.getLocked());
}
});
Button button2 = new Button(bar, SWT.PUSH);
button2.setText("Another button");
button2.pack();
ToolBar tools = new ToolBar(bar, SWT.NONE);
ToolItem b1 = new ToolItem(tools, SWT.FLAT);
b1.setText("Tool");
ToolItem b2 = new ToolItem(tools, SWT.FLAT);
b2.setText("Bar");
tools.pack();
Point size = button1.getSize();
item1.setControl(button1);
item1.setSize(item1.computeSize(size.x, size.y));
size = button2.getSize();
item2.setControl(button2);
item2.setSize(item2.computeSize(size.x, size.y));
size = tools.getSize();
item3.setControl(tools);
item3.setSize(item3.computeSize(size.x, size.y));
item3.setMinimumSize(size);
通過創建簡單的按鈕,併爲按鈕添加監聽器,來禁止和啓用拖拽功能。然後創建了包含兩個按鈕的工具欄,並添加到CoolBar中。然後可以通過CoolItem的setControl方法來將CoolItem與空間聯繫起來,然後通過setSize方法來設置空間的初始值。通過設置setMinimumSize方法,用戶可以調整CoolItem的大小。最後,通過調用setWrapIndices來將CoolItem隔開。使用setSize來指定在shell中的大小。
參考資料:
SWT主頁:http://www.eclipse.org/swt
SWT小例子:http://www.eclipse.org/swt/snippets/
SWT例子:http://www.eclipse.org/swt/examples.php
SWT文檔:http://www.eclipse.org/swt/docs.php
Getting Started with Eclipse 2.1 and the SWT:http://www.cs.umanitoba.ca/~eclipse/