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 }
复制代码

 


本文转自ZH奶酪博客园博客,原文链接:http://www.cnblogs.com/CheeseZH/archive/2013/03/26/2982841.html,如需转载请自行联系原作者

相关文章
|
3天前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。
|
15天前
|
监控 安全 Java
在 Java 中使用线程池监控以及动态调整线程池时需要注意什么?
【10月更文挑战第22天】在进行线程池的监控和动态调整时,要综合考虑多方面的因素,谨慎操作,以确保线程池能够高效、稳定地运行,满足业务的需求。
96 38
|
12天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
|
2天前
|
存储 安全 Java
Java多线程编程的艺术:从基础到实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及其实现方式,旨在帮助开发者理解并掌握多线程编程的基本技能。文章首先概述了多线程的重要性和常见挑战,随后详细介绍了Java中创建和管理线程的两种主要方式:继承Thread类与实现Runnable接口。通过实例代码,本文展示了如何正确启动、运行及同步线程,以及如何处理线程间的通信与协作问题。最后,文章总结了多线程编程的最佳实践,为读者在实际项目中应用多线程技术提供了宝贵的参考。 ####
|
2天前
|
Java
JAVA多线程通信:为何wait()与notify()如此重要?
在Java多线程编程中,`wait()` 和 `notify()/notifyAll()` 方法是实现线程间通信的核心机制。它们通过基于锁的方式,使线程在条件不满足时进入休眠状态,并在条件满足时被唤醒,从而确保数据一致性和同步。相比其他通信方式,如忙等待,这些方法更高效灵活。 示例代码展示了如何在生产者-消费者模型中使用这些方法实现线程间的协调和同步。
9 3
|
1天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
2天前
|
Java
java小知识—进程和线程
进程 进程是程序的一次执行过程,是系统运行的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就是一个执行中的程序,它在计算机中一个指令接着一个指令地执行着,同时,每个进程还占有某些系统资源如CPU时间,内存空间,文件,文件,输入输出设备的使用权等等。换句话说,当程序在执行时,将会被操作系统载入内存中。 线程 线程,与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中产生多个线程。与进程不同的是同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是在各个线程之间做切换工作时,负担要比
7 1
|
2天前
|
Java UED
Java中的多线程编程基础与实践
【10月更文挑战第35天】在Java的世界中,多线程是提升应用性能和响应性的利器。本文将深入浅出地介绍如何在Java中创建和管理线程,以及如何利用同步机制确保数据一致性。我们将从简单的“Hello, World!”线程示例出发,逐步探索线程池的高效使用,并讨论常见的多线程问题。无论你是Java新手还是希望深化理解,这篇文章都将为你打开多线程的大门。
|
2天前
|
安全 Java 编译器
Java多线程编程的陷阱与最佳实践####
【10月更文挑战第29天】 本文深入探讨了Java多线程编程中的常见陷阱,如竞态条件、死锁、内存一致性错误等,并通过实例分析揭示了这些陷阱的成因。同时,文章也分享了一系列最佳实践,包括使用volatile关键字、原子类、线程安全集合以及并发框架(如java.util.concurrent包下的工具类),帮助开发者有效避免多线程编程中的问题,提升应用的稳定性和性能。 ####
20 1
|
6天前
|
存储 设计模式 分布式计算
Java中的多线程编程:并发与并行的深度解析####
在当今软件开发领域,多线程编程已成为提升应用性能、响应速度及资源利用率的关键手段之一。本文将深入探讨Java平台上的多线程机制,从基础概念到高级应用,全面解析并发与并行编程的核心理念、实现方式及其在实际项目中的应用策略。不同于常规摘要的简洁概述,本文旨在通过详尽的技术剖析,为读者构建一个系统化的多线程知识框架,辅以生动实例,让抽象概念具体化,复杂问题简单化。 ####
下一篇
无影云桌面