SWT 中的UI 线程

SWT中 Display 对象就是一个UI 线程。

若要访问UI 界面上的对象必须通过UI线程来访问,在非UI 线程内访问UI对象是不允许的。

 

我们看这个程序:

 

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.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Shell;


public class ProgressBarComplex {
	static boolean bCancel = false;
	public static void main(String[] args){
		Display display = new Display();
		final Shell shell = new Shell(display);
		shell.setText("ProgressBar");
		shell.setLayout(new GridLayout(2,false));
		final Button start = new Button(shell, SWT.NONE);
		start.setText("开始");
		Button cancel = new Button(shell, SWT.NONE);
		cancel.setText("取消");
		final ProgressBar progressBar = new ProgressBar(shell, SWT.HORIZONTAL);
		GridData data = new GridData();
		data.horizontalSpan = 2;
		data.grabExcessHorizontalSpace = true;
		progressBar.setLayoutData(data);
		progressBar.setMaximum(100);
		progressBar.setMinimum(0);
		final int maximum = progressBar.getMaximum();
		final int minimus = progressBar.getMinimum();
		
		start.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e){
				start.setEnabled(false);
				
				Runnable runnable = new Runnable(){
					public void run(){
						for(int i=minimus;i<maximum;i++){
							try{
								Thread.sleep(100);
							}catch(InterruptedException e){
							}
							
							//用 asyncExec 异步执行
							shell.getDisplay().asyncExec(new Runnable(){
								public void run(){
									if(progressBar.isDisposed())
										return;
									if(bCancel){
										progressBar.setSelection(0);
									}
									//只能在 UI 线程内调用,不能直接调用UI 元素的setSelection 函数
									progressBar.setSelection(progressBar.getSelection()+1);
								}
							});
							
							if(bCancel){
								bCancel = false;
								break;
							}
						}
					}
				};
				new Thread(runnable).start();
			}
		});
		
		cancel.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e){
				if(!bCancel){
					bCancel = true;
					start.setEnabled(true);
				}
			}
		});
		shell.pack();
		shell.open();
		while(!shell.isDisposed()){
			if(!display.readAndDispatch())
				display.sleep();
		}
	}
}


函数 progressBar.setSelection() 是包含在一个Runnable 中,即在一个非UI 线程的线程中。由于progressBar 属于UI 对象,因此访问它的方法必须使用Dispaly 的线程调度方法,正如上面程序所示。

 

在Display 中进行线程调度的方法有3种:

1. asyncExec(Runnable): 异步执行线程,即这个调用的asyncExec 函数的线程可以和runnable 线程同步执行

2. syncExec(Runnable):等待runnable函数执行完毕才能继续。

3. timerExec(int milliseconds, Runnable runnable):等待一段时间后才开始新线程runnable。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值