SWT 中的UI 线程

来源:互联网 发布:软件架构工具 编辑:程序博客网 时间:2024/05/04 15:06

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。

 

原创粉丝点击