码迷,mamicode.com
首页 > 编程语言 > 详细

SWT Designer 下 SWT的线程(*转*)

时间:2015-02-28 12:47:57      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:

简介

        多数情况下,GUI界面编程不需要考虑线程问题,SWT已经帮助我们隐藏了底层的线程调用。但一些特殊应用,却不得不涉及SWT线程编程。

        在实际项目开发中,一种常见的应用是:单击前台界面的执行后,在后台要做一些任务处理,任务执行情况要反映在界面上,而且还不能影响前台界面的其他操作这种应用的实现思路如下:

  前台界面和后台程序分开2个类。

  为后台程序另开一个线程,这样就可以让前台操作不受后台影响了。

  前台界面提供一些可操作的组件的方法,后台处理程序调用这些方法,将执行情况的字符串写到前台界面组件中。

  这种思路必须解决一个关键问题:界面本身有一个默认线程,后台程序又是另外一个线程。那么该如何在一个线程中访问另外一个线程呢?

        (1) 为后台新开一个线程,这要用到JDK中线程的知识,代码如下:

     new Thread()...{ // 新开一个线程,这是匿名内部类的写法

       public void run()...{

       //开始后台任务

              }

          }.start();//start表示立即开始线程

       (2) 从后台处理线程中访问前台界面组件,关键在于使用display对象,因为display主要负责管理时间循环和控制UI线程和其他线程之间的通信。display的具体使用方法如下:

         Display.getDefault().asyncExec(new Runnable()...{//又是一个匿名内部类写法

      public void run()...{

       //对前台界面的操作

              }

         });

      在这里的display对象很关键,因此顺便给出得到display对象的2种方法:

  Display.getDefault(),得到一个默认的display对象,应用程序一般只需要一个display对象。

  Display.getCurrent(),得到当前运行线程所在的display对象,如果生成2个以上的display对象,则可用此方法。

  

  一个SWT线程的实例:

  本实例分2个类:一个前台界面类,一个后台处理类。实例功能说明如下:

      单击“GO”按钮时,开始后台处理。

      单击“STOP”按钮,立即中断后台处理。

      后台处理的任务数根据前台界面文本框的值来决定。

      进度条将实时反映后台处理的进度。

      底部的文本框将以文字形式反映后台处理的进度情况。

      实例具体代码如下:

1. 前台界面类

import org.eclipse.swt.SWT;

import org.eclipse.swt.events.SelectionAdapter;

import org.eclipse.swt.events.SelectionEvent;

import org.eclipse.swt.events.VerifyEvent;

import org.eclipse.swt.events.VerifyListener;

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.Group;

import org.eclipse.swt.widgets.Label;

import org.eclipse.swt.widgets.ProgressBar;

import org.eclipse.swt.widgets.Shell;

import org.eclipse.swt.widgets.Text;

 

public class TaskGUI ...{

 private Display display = Display.getDefault();

 private Shell shell = new Shell();

 private Task task = new Task(this);//Task是后台处理类,需要传入一个TaskGUI类型参数

 //将界面组件设为类的实例变量

 private Text taskCountText;//可输入任务数的文本框

 private Button startButton;//开始

 private Button stopButton;//结束

 private ProgressBar progressBar;//显示的任务条

 private Text consoleText;//显示当前后台进度的信息条

 //主函数

 public static void main(String[] args)...{

 try...{

            TaskGUI window = new TaskGUI();

            window.open();

        }catch(Exception e)...{

            e.printStackTrace();

        }

    }

 //前台页面的执行方法,显示出可操作的前台界面、

 public void open() ...{

        shell.setSize(300,300);

        shell.setLayout(new GridLayout());

        Group group = new Group(shell,SWT.NONE);

        group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        group.setLayout(new GridLayout(4,false));

 

 new Label(group,SWT.NONE).setText("taskCount:");

        taskCountText = new Text(group,SWT.BORDER);

        taskCountText.setText("10");

        taskCountText.setLayoutData(new GridData(100,-1));

        taskCountText.addVerifyListener(new VerifyListener()...{

 public void verifyText(VerifyEvent e) ...{ //only input NO.

                e.doit = "0123456789".indexOf(e.text)>=0;              

            }

        });

        startButton = new Button(group,SWT.PUSH);

        startButton.setText("GO");

        startButton.addSelectionListener(new SelectionAdapter() ...{//点击开始按钮

 public void widgetSelected(SelectionEvent e) ...{

                setButtonState(false);//点击后,2个Button发生变化

 //得到任务数,多线程使用的变量要求类型为final

                String str = taskCountText.getText();

 final int taskCount = new Integer(str).intValue();

 //设置进度条的格数

                progressBar.setMaximum(taskCount-1);

                consoleText.insert("back Thread run start... ...  ");

 //为后台新开一个线程,运行,当run方法结束(即后台的start()结束),线程自动销毁

 new Thread()...{

 public void run()...{

                        task.start(taskCount);

                    }

                }.start();

                consoleText.insert("back Thread run end... ...  ");

            }

        });

        stopButton = new Button(group,SWT.PUSH);

        stopButton.setText("STOP");

        stopButton.setEnabled(false);      

        stopButton.addSelectionListener(new SelectionAdapter() ...{

 public void widgetSelected(SelectionEvent e) ...{

                task.stop();//后台执行stop方法,实际是要后台任务停止

            }

        });

        progressBar = new ProgressBar(shell,SWT.NONE);

        progressBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

 //下面2个是设置,文本框的显示格式,第2行的如果不加则会看不到全部信息了

        consoleText = new Text(shell,SWT.MULTI|SWT.BORDER|SWT.V_SCROLL);

        consoleText.setLayoutData(new GridData(GridData.FILL_BOTH));

        shell.layout();

        shell.open();

 while(!shell.isDisposed())...{

 if(!display.readAndDispatch())...{

                display.sleep();

            }

        }

    }

 public void setButtonState(boolean bFlag)...{//设置页面的2个按钮状态

        startButton.setEnabled(bFlag);

        stopButton.setEnabled(!bFlag);

    }

 //为后台取得页面组件写的几个GET方法

 public Shell getShell()...{

 return shell;

    }

 public Text getConsoleText()...{

 return consoleText;

    }

 public ProgressBar getProgressBar()...{

 return progressBar;

    }

}

2. 后台任务类

import org.eclipse.swt.widgets.Display;

public class Task ...{

 private TaskGUI gui;//通过构造器得到前台界面对象

 private boolean stopFlag;//是否停止的标志

 //构造器 取得前台界面对象

 public Task(TaskGUI taskGUI)...{

 this.gui = taskGUI;

    }

 public void stop()...{

        stopFlag = true;

    }

 //就是前台run方法的执行内容,这个方法结束,则前台new的那个线程销毁

 public void start(int taskCount)...{

        stopFlag = false;//将执行状态初始化执行

        insertConsoleText("backGO start ... ...  ");

 for(int i=0;i<taskCount;i++)...{

 if(stopFlag)...{//点击stop按钮则这个属性为true,跳出循环

 break;

            }

 try...{//每隔1秒一次循环

                Thread.sleep(1000);

            }catch(InterruptedException e)...{

                e.printStackTrace();

            }

 //页面上的信息累加

            insertConsoleText("task"+(i+1)+"the end ");

 //移动进度条的进度

            moveProgressBar(i);

        }

        insertConsoleText("the thread end of the task!! ");      

        setTaskGUIButtonState(true);

    }

 //修改页面按钮的状态

 private void setTaskGUIButtonState(final boolean bFlag)...{

        Display.getDefault().asyncExec(new Runnable()...{

 public void run()...{

               gui.setButtonState(bFlag);

           }

        });

    }

 private void moveProgressBar(final int progress)...{

        Display.getDefault().asyncExec(new Runnable()...{

 public void run()...{

                gui.getProgressBar().setSelection(progress);

            }

         });

    }

 private void insertConsoleText(final String str)...{

        Display.getDefault().asyncExec(new Runnable()...{

 public void run()...{

                gui.getConsoleText().insert(str);

            }

         });

    }

}

程序说明:

从上面代码的执行结果可以看到,前台new 了一个新的 thread 后,后面的那句文本依然可以输出,可以明确的说明,new了一个线程后,前台,后台线程是互不干扰的独自运行。当start方法结束时,后台的线程就自动销毁。

SWT Designer 下 SWT的线程(*转*)

标签:

原文地址:http://www.cnblogs.com/mengtao-liu/p/4305021.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!