网站很久没更新了,最近忙着写《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;
}
}