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

简介

多数情况下,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方法结束时,后台的线程就自动销毁。

时间: 2024-08-03 08:48:55

SWT Designer 下 SWT的线程(*转*)的相关文章

Windowbuilder之swt designer安装与使用(转)

SWT可视化设计,可以使用Google的WindowBuilder. 在Google Code中,搜索WindowBuilder就可以看到路径. 在Eclipse中   Help--->Install New Software--->输入网址安装. http://www.cnblogs.com/wangjiyuan/p/3334902.html Swt designer是eclipse的图形界面设计的插件.在sun被google收购后,swt就没有再更新了,尤其是高版本的eclipse更难找到

eclipse SWT Designer 插件详解

今天本来想用swing做个小软件,就搜了下eclipse插件,果然有. 先下swt zip包,地址:http://www.eclipse.org/windowbuilder/download.php 1.选择自己eclipse对应的版本,eclipse版本查看:help→about eclipse. 2.然后help→install new software.选中1中下载的zip包,然后傻瓜式地一直下一步.完了eclipse progress进度条会显示安装中... 如图: 3. 安装好后直接n

嵌入式环境下并发控制与线程安全

嵌入式环境下并发控制与线程安全 代码规模日益增大和基于RTOS的多线程技术使嵌入式软件开发越来越关注"并发控制和线程安全",当多个执行线程(指正在运行代码的任意上下文,包括线程和中断服务程序)需要访问相同的共享资源时(包括软件数据和硬件资源),就可能因为竞态而导致错误.这种错误容易制造,但很难找到,从设计上保证正确性收益更大. 竞态的产生 当一个共享资源被多个执行线程"非原子性"访问时,一个执行线程的操作被另一个执行线程打断而带来错误就叫"竞态"

[笔记]linux下和windows下的 创建线程函数

linux下和windows下的 创建线程函数 1 #ifdef __GNUC__ 2 //Linux 3 #include <pthread.h> 4 #define CreateThreadEx(tid,threadFun,args) pthread_create(tid, 0, threadFun, args) 5 #define CloseHandle(ph) 6 7 int pthread_create( 8 //指向线程标识符的指针. 9 pthread_t *restrict t

多线程下的进程同步(线程同步问题总结篇)

之前写过两篇关于线程同步问题的文章(一,二),这篇中将对相关话题进行总结,本文中也对.NET 4.0中新增的一些同步机制进行了介绍. 首先需要说明的是为什么需要线程功能同步.MSDN中有这样一段话很好的解释了这个问题: 当多个线程可以调用单个对象的属性和方法时,对这些调用进行同步处理是非常重要的.否则,一个线程可能会中断另一个线程正在执行的任务,使该对象处于一种无效状态. 也就说在默认无同步的情况下,任何线程都可以随时访问任何方法或字段,但一次只能有一个线程访问这些对象.另外,MSDN中也给出定

LINUX下的简单线程池

前言 任何一种设计方式的引入都会带来额外的开支,是否使用,取决于能带来多大的好处和能带来多大的坏处,好处与坏处包括程序的性能.代码的可读性.代码的可维护性.程序的开发效率等. 线程池适用场合:任务比较多,需要拉起大量线程来处理:任务的处理时间相对比较短,按照线程的周期T1(创建阶段).T2(执行阶段).T3(销毁阶段)来算,执行阶段仅占用较少时间. 简单的线程池通常有以下功能:预创建一定数量的线程:管理线程任务,当工作线程没有事情可做时休眠自己:销毁线程池. 复杂一些的线程池有额外的调节功能:管

Linux 下进程与线程的基本概念

2019-10-01 关键字:进程.线程.信号量.互斥锁 什么是程序? 程序就是存放在磁盘上的指令和数据的有序集合,就是源代码编译产物. 它是静态的. 什么是进程? 进程就是操作系统为执行某个程序所分配的资源的总称.进程是程序的一次执行过程,因此它与程序不同,它是动态的.它的生命周期包括创建.调度.执行和消亡. 进程的内容主要包括以下三个部分: 1.正文段: 2.用户数据段: 3.系统数据段. 其中正文段与用户数据段两部分是从程序当中来的.而系统数据段则是操作系统分配的用来管理这个进程用的. 系

linux下将不同线程绑定到不同core和cpu上——pthread_setaffinity_np

=============================================================== linux下的单进程多线程的程序,要实现每个线程平均分配到多核cpu,主要有2个方法 1:利用linux系统自己的线程切换机制,linux有一个服务叫做irqbalance,这个服务是linux系统自带的,默认会启动,这个服务的作用就是把多线程平均分配到CPU的每个核上面,只要这个服务不停止,多线程分配就可以自己实现.但是要注意,如果线程函数内部的有某个循环,且该循环内

Python下进程与线程的原理及区别

对于所有的语言都可能会遇到进程和线程的问题,一般情况下线程是由进程产生的,一个进程产生多个线程来按照一定的规则(Python下根据CPU调度算法和全局进程锁)来利用CPU,我们称之为多线程模式:而一个进程在产生的同时,同时会生成一个主线程,如果程序生成多个进程,那么每个进程都会产生一个线程,多个程序按照一定的规则去利用CPU,我们称之为多进程模式.                 Python下多线程与多进程关系图原理如下所示: