Java SWT线程

在SWT的线程开发中,基本思路是:将前台和后台分开为两个类;为后台处理开辟一个线程,让前台和后台处理相互不受影响;前台提供一些组件的操作方法,后台调用方法,并将执行情况写入到前台的组件中显示。

在SWT线程开发中,如果使用一个线程去访问另一个线程,则需要使用到Display对象的asyncExce方法,或者syncExce方法;

在关闭前台窗口时,需要将后台工作停止。由于是多线程,前台窗口关闭后,后台的程序还会在运行,并且回访问到前台的方法,这时,需要调用stop方法,使后台即使停止工作。

下边是一个示例:

前台运行类:

1:前台类中要有一个后台类成员,以便用this进行构造后台类;

2:前台类中要把后台需要访问的界面中的组件设为类的实例变量;

3:在前台类的main中实例化一个前台类对象,并调用open函数进行初始化;

4:前台类的open函数中对窗口进行基本的布局(创建按钮、标签、文本框等)并为组件添加事件监听;

5:可以把后台线程的创建放在事件监听中,也可以放在其外;

  1 package cn.com.sino.swt;
  2 
  3 import org.eclipse.swt.SWT;
  4 import org.eclipse.swt.events.SelectionAdapter;
  5 import org.eclipse.swt.events.SelectionEvent;
  6 import org.eclipse.swt.events.VerifyEvent;
  7 import org.eclipse.swt.events.VerifyListener;
  8 import org.eclipse.swt.layout.GridData;
  9 import org.eclipse.swt.layout.GridLayout;
 10 import org.eclipse.swt.widgets.Button;
 11 import org.eclipse.swt.widgets.Display;
 12 import org.eclipse.swt.widgets.Group;
 13 import org.eclipse.swt.widgets.Label;
 14 import org.eclipse.swt.widgets.ProgressBar;
 15 import org.eclipse.swt.widgets.Shell;
 16 import org.eclipse.swt.widgets.Text;
 17 
 18 public class GUITest01 {
 19     private Display display = Display.getDefault();
 20     private Shell shell = new Shell();
 21     private GUITest task = new GUITest(this);                    //task为后台处理类
 22     //将界面组件设为类的实例变量
 23     private Text taskText;                                        //创建任务数文本框
 24     private Button openButton;                                    //创建“执行”按钮
 25     private Button stopButton;                                    //创建“停止”按钮
 26     private ProgressBar progressBar;                            //创建进度条
 27     private Text consoleText;                                    //创建输出调试信息的文本框
 28     
 29     public static void main(String[] args) {                    //main方法
 30         try {
 31             GUITest01 window = new GUITest01();                    //创建窗口
 32             window.open();                                        //打开窗口
 33         } catch (Exception e) {
 34             e.printStackTrace();
 35         }
 36     }
 37     
 38     public void open(){
 39         shell.setSize(330,330);                                    //设置窗口大小
 40         shell.setLayout(new GridLayout());                        //设置窗口布局
 41         shell.setText("SWT线程示例");                                //设置窗口标题
 42         Group group = new Group(shell, SWT.NONE);                //设置任务数文本框和按钮的组
 43         group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 44         group.setLayout(new GridLayout(4,false));
 45         new Label(group, SWT.NONE).setText("任务数:");            //设置任务数文本框
 46         taskText = new Text(group, SWT.BORDER);
 47         taskText.setText("20");                                    //默认任务数
 48         taskText.setLayoutData(new GridData(100,-1));
 49         taskText.addVerifyListener(new VerifyListener() {    
 50             public void verifyText(VerifyEvent e) {                //只能输入数值
 51                 e.doit = "0123456789".indexOf(e.text) >=0;                
 52             }
 53         });
 54         openButton = new Button(group, SWT.PUSH);                //创建执行按钮
 55         openButton.setText("执行");
 56         //对按钮添加事件监听
 57         openButton.addSelectionListener(new SelectionAdapter() {
 58             public void widgetSelected(SelectionEvent e) {
 59                 setButtonState(false);                            //设置两按钮的状态
 60                 String str = taskText.getText();                //得到任务数
 61                 final int taskCount = new Integer(str).intValue();
 62                 progressBar.setMaximum(taskCount-1);            //设置进度条的格数
 63                 consoleText.insert("后台处理线程开始启动......\n");
 64                 
 65                 new Thread(){                                    //为后台任务创建一个新的线程
 66                     public void run(){
 67                         task.start(taskCount);
 68                     }
 69                 }.start();
 70                 
 71                 consoleText.insert("后台处理线程启动结束。\n");
 72             }
 73         });
 74         
 75         stopButton = new Button(group, SWT.PUSH);                //创建停止按钮
 76         stopButton.setText("停止");
 77         stopButton.setEnabled(false);                            //设置按钮是否可用
 78         //对按钮添加事件监听
 79         stopButton.addSelectionListener(new SelectionAdapter() {
 80             public void widgetSelected(SelectionEvent e){
 81                 task.stop();                                    //后台任务停止
 82             }
 83         });
 84         
 85         progressBar = new ProgressBar(shell, SWT.NONE);            //创建进度条
 86         progressBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 87         //输出调试信息的文本框
 88         consoleText = new Text(shell, SWT.MULTI|SWT.BORDER|SWT.V_SCROLL);
 89         consoleText.setLayoutData(new GridData(GridData.FILL_BOTH));
 90         //------------------------------------------------------
 91         shell.layout();
 92         shell.open();
 93         while(!shell.isDisposed()){
 94             if(!display.readAndDispatch()){
 95                 display.sleep();
 96             }
 97         }
 98         display.dispose();
 99     }
100     public void setButtonState(boolean bFlag){
101         openButton.setEnabled(bFlag);
102         stopButton.setEnabled(!bFlag);
103     }
104     //以下为后台类取界面组件的几个get方法
105     public Shell getShell(){
106         return shell;
107     }
108     public Text getConsoleText(){
109         return consoleText;
110     }
111     public ProgressBar getProgressBar(){
112         return progressBar;
113     }
114 }

后台运行类:

1:后台类中要有一个前台界面对象,在构造时获取;

2:在对前台操作的函数中需要调用syncExec,再调用界面类的函数(自定义,可以获取界面组件对象)对界面组件操作;

 1 package cn.com.sino.swt;
 2 
 3 import org.eclipse.swt.widgets.Display;
 4 
 5 public class GUITest {
 6     private GUITest01 guitest;//前台界面对象
 7     private boolean stopFlag;//是否停止的标识
 8     
 9     /**
10      * 取得前台界面兑现
11      * @param taskGUI
12      */
13     public GUITest(GUITest01 taskGUI){
14         this.guitest = taskGUI;
15     }
16     /**
17      * 停止执行
18      */
19     public void stop(){
20         stopFlag = true;
21     }
22     /**
23      * 开始执行
24      * @param taskCount
25      */
26     public void start(int taskCount){
27         stopFlag = false;//将执行状态初始化成执行
28         intsertConsoleText("------后台线程开始执行任务------\n");
29         for (int i = 0; i < taskCount; i++) {
30             if(stopFlag)//如果发现执行状态为停止,则退出次循环
31                 break;
32             try {
33                 Thread.sleep(500);//0.5秒一次循环
34             } catch (InterruptedException e) {
35                 e.printStackTrace();
36             }
37             intsertConsoleText("开始处理第"+(i+1)+"个任务...\n");//设置文本内容
38             try {
39                 Thread.sleep(500);//休眠0.5秒
40             } catch (InterruptedException e) {
41                 e.printStackTrace();
42             }
43             intsertConsoleText("任务"+(i+1)+"处理完毕\n");
44             moveProgressBar(i);//设置进度条移动
45         }
46         intsertConsoleText("------后台线程结束执行任务------\n");
47         setTaskGUIButtonState(true);//刷新界面按钮状态
48     }
49     /**
50      * 界面按钮状态
51      * @param bFlag
52      */
53     private void setTaskGUIButtonState(final boolean bFlag){
54         Display.getDefault().asyncExec(new Runnable() {
55             @Override
56             public void run() {
57                 guitest.setButtonState(bFlag);    
58             }
59         });
60     }
61     /**
62      * 显示进度条
63      * @param progress
64      */
65     private void moveProgressBar(final int progress){
66         Display.getDefault().syncExec(new Runnable() {
67             
68             @Override
69             public void run() {
70                 guitest.getProgressBar().setSelection(progress);
71                 
72             }
73         });
74     }
75     /**
76      * 文本插入
77      * @param str
78      */
79     private void intsertConsoleText(final String str) {
80         Display.getDefault().syncExec(new Runnable() {
81             
82             @Override
83             public void run() {
84                 guitest.getConsoleText().insert(str);
85                 
86             }
87         });
88     }
89 }

 

posted @ 2013-03-26 16:33  ZH奶酪  阅读(1986)  评论(0编辑  收藏  举报