網站很久沒更新了,最近忙著寫《Eclipse從入門到精通》的第二版,因為SWT API變化的原因,程序全驗證了一篇,有些實例重寫了,還增加了很多內容。這里是新增的一個實例,來源于一個讀者的提問。
這一節將實現一個如圖13.2所示的實例。為了能看清更面板的框架,把面板都設成了邊框型。實例有以下內容:
q??????? 如何創建一個簡單的狀態欄(基于RCP平臺能夠直接使用它的進度條服務)
q??????? 如何在狀態欄中動態創建進度條,同時如何用完后銷毀它。
q??????? 如何用exclude屬性、setVisible和layout方法來動態顯示/隱藏面板或組件。
q??????? 再次表明在一個線程Thread里調用SWT組件都要用display.asyncExec()包裝一下,而且還要在使用組件前對其是否被銷毀做判斷

??
圖13.2 狀態欄里的進度條
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;
publicclass ProgressBar3 {
???????? private Display display;
???????? private Shell shell;
???????? private Composite statusbar;
???????? private Label statusbarLabel;
???????? private ProgressBar progressBar;
???????? private Button hideProbarButton;
???????? publicstaticvoid main(String[] args) {????? new ProgressBar3().open();???? }
???????? privatevoid open() {
?????????????????? display = Display.getDefault();
?????????????????? shell = new Shell();
?????????????????? shell.setSize(250, 170);
?????????????????? // ---------創建窗口中的其他界面組件-------------
?????????????????? shell.setLayout(new GridLayout());
?????????????????? createMainComp(shell);//創建主面板
?????????????????? createStatusbar(shell);//創建工具欄
?????????????????? // -----------------END------------------------
?????????????????? shell.layout();
?????????????????? shell.open();
?????????????????? while (!shell.isDisposed()) {
??????????????????????????? if (!display.readAndDispatch())
???????????????????????????????????? display.sleep();
?????????????????? }
?????????????????? display.dispose();
???????? }
???????? privatevoid createMainComp(Composite parent) {
?????????????????? Composite comp = new Composite(parent, SWT.BORDER);
?????????????????? comp.setLayoutData(new GridData(GridData.FILL_BOTH));
?????????????????? comp.setLayout(new RowLayout());
?????????????????? createButton(comp);
???????? }
???????? privatevoid createButton(Composite parent) {
?????????????????? final Button b1 = new Button(parent, SWT.NONE);
?????????????????? b1.setText("隱藏狀態欄");
?????????????????? b1.addSelectionListener(new SelectionAdapter() {
??????????????????????????? privatebooleanflag = true;
??????????????????????????? publicvoid widgetSelected(SelectionEvent e) {
???????????????????????????????????? // 用statusbar.setVisible(false)來隱藏狀態欄是不夠的,還必須把它占用的空間也釋放出來,這時應該用GridData.exclude
???????????????????????????????????? GridData data = (GridData) statusbar.getLayoutData();
???????????????????????????????????? data.exclude = flag;
???????????????????????????????????? shell.layout();
???????????????????????????????????? b1.setText((flag ? "顯示" : "隱藏") + "狀態欄");
???????????????????????????????????? flag = !flag;
??????????????????????????? }
?????????????????? });
?????????????????? hideProbarButton = new Button(parent, SWT.NONE);
?????????????????? hideProbarButton.setText("隱藏進度條");
?????????????????? hideProbarButton.setEnabled(false);
?????????????????? hideProbarButton.addSelectionListener(new SelectionAdapter() {
??????????????????????????? privatebooleanflag = false;
??????????????????????????? publicvoid widgetSelected(SelectionEvent e) {
???????????????????????????????????? progressBar.setVisible(flag);
???????????????????????????????????? hideProbarButton.setText((flag ? "隱藏" : "顯示") + "進度條");
???????????????????????????????????? flag = !flag;
??????????????????????????? }
?????????????????? });
?????????????????? final Button b3 = new Button(parent, SWT.NONE);
?????????????????? b3.setText(" GO ");
?????????????????? b3.addSelectionListener(new SelectionAdapter() {
??????????????????????????? privatebooleanstopFlag = true;
??????????????????????????? publicvoid widgetSelected(SelectionEvent e) {
???????????????????????????????????? stopFlag = !stopFlag;
???????????????????????????????????? if (stopFlag) // 根據停止標志stopFlag來判斷是停止還是運行
?????????????????????????????????????????????? stop();
???????????????????????????????????? else
?????????????????????????????????????????????? go();
??????????????????????????? }
??????????????????????????? privatevoid stop() {
???????????????????????????????????? b3.setEnabled(false);// 停止需要時間,在完全停止前要防止再次開始。
???????????????????????????????????? b3.setText("GO");
??????????????????????????? }
??????????????????????????? privatevoid go() {
???????????????????????????????????? b3.setText("STOP");
???????????????????????????????????? progressBar = createProgressBar(statusbar);
???????????????????????????????????? hideProbarButton.setEnabled(true);
???????????????????????????????????? statusbar.layout();// 重新布局一下工具欄,使進度條顯示出來
???????????????????????????????????? new Thread() {
?????????????????????????????????????????????? publicvoid run() {
??????????????????????????????????????????????????????? for (int i = 1; i < 11; i++) {
???????????????????????????????????????????????????????????????? if (display.isDisposed() || stopFlag) {
?????????????????????????????????????????????????????????????????????????? disposeProgressBar();
?????????????????????????????????????????????????????????????????????????? return;
???????????????????????????????????????????????????????????????? }
???????????????????????????????????????????????????????????????? moveProgressBar(i);
???????????????????????????????????????????????????????????????? try {? Thread.sleep(1000);????????? } catch (Throwable e2) {} //停一秒
??????????????????????????????????????????????????????? }
??????????????????????????????????????????????????????? disposeProgressBar();
?????????????????????????????????????????????? }
?????????????????????????????????????????????? privatevoid moveProgressBar(finalint i) {
??????????????????????????????????????????????????????? display.asyncExec(new Runnable() {
???????????????????????????????????????????????????????????????? publicvoid run() {
?????????????????????????????????????????????????????????????????????????? if (!statusbarLabel.isDisposed())
??????????????????????????????????????????????????????????????????????????????????? statusbarLabel.setText("前進到第" + i + "步");
?????????????????????????????????????????????????????????????????????????? if (!progressBar.isDisposed())
??????????????????????????????????????????????????????????????????????????????????? progressBar.setSelection(i * 10);
???????????????????????????????????????????????????????????????? }
??????????????????????????????????????????????????????? });
?????????????????????????????????????????????? }
?????????????????????????????????????????????? privatevoid disposeProgressBar() {
??????????????????????????? ??????????????????????????? if (display.isDisposed())?? return;
??????????????????????????????????????????????????????? display.asyncExec(new Runnable() {
???????????????????????????????????????????????????????????????? publicvoid run() {
?????????????????????????????????????????????????????????????????????????? hideProbarButton.setEnabled(false);
??????????????????????????? // 這一句不能放在線程外執行,否則progressBar被創建后就立即被dispose了
?????????????????????????????????????????????????????????????????????????? progressBar.dispose();
?????????????????????????????????????????????????????????????????????????? b3.setEnabled(true);
???????????????????????????????????????????????????????????????? }
??????????????????????????????????????????????????????? });
?????????????????????????????????????????????? }
???????????????????????????????????? }.start();
??????????????????????????? }
?????????????????? });
???????? }
???????? privatevoid createStatusbar(Composite parent) {
?????????????????? statusbar = new Composite(parent, SWT.BORDER);
?????????????????? //設置工具欄在Shell中的形狀為水平搶占充滿,并高19像素
?????????????????? GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
?????????????????? gridData.heightHint = 19;
?????????????????? statusbar.setLayoutData(gridData);
?????????????????? //設置為用行列式布局管理狀態欄里的組件
?????????????????? RowLayout layout = new RowLayout();
?????????????????? layout.marginLeft = layout.marginTop = 0; //無邊距
?????????????????? statusbar.setLayout(layout);
?????????????????? //創建一個用于顯示文字的標簽
?????????????????? statusbarLabel = new Label(statusbar, SWT.BORDER);
?????????????????? statusbarLabel.setLayoutData(new RowData(70, -1));
???????? }
???????? //創建進度條
???????? private ProgressBar createProgressBar(Composite parent) {
?????????????????? ProgressBar progressBar = new ProgressBar(parent, SWT.SMOOTH);
?????????????????? progressBar.setMinimum(0); // 最小值
?????????????????? progressBar.setMaximum(100);// 最大值
?????????????????? return progressBar;
???????? }
}