SWT 启用另一个线程处理耗时事务

在SWT UI应用中,点击开始按钮启动后台线程进行网站爬取时遇到Invalid thread access异常。原因是SWT的单线程限制,只允许主线程操作组件。解决方案是使用Display.asyncExec或Display.syncExec在主线程中执行相关操作。
摘要由CSDN通过智能技术生成

这两天闲来无聊,做了一个SWT的UI,发现个问题。准备在UI上点击一个开始按钮,然后后台执行启动一个线程,这个线程到网站上爬东西去。但是在线程访问SWT中组件的时候发生了Invalid thread access异常,查了一些资料,说是SWT单线程机制中,会检测当前线程是否是主线程。到网上找一些资料大家推荐用如下:

Display.getDefault().asyncExec(runnable)
我也是第一次做桌面的东西,所以走了一段弯路,最后在百度文库上找到一个兄弟的方法。做了一个小例子和大家分享。UI方面重要在最下面的三个按钮监听

下面是线程类:

package com.yue.thread;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;

public class MyThread extends Thread {

	private Display display;
	
	private Text text;
	
	private int index = 0;
	
	private boolean flag = true;
	
	public MyThread(Display display,Text text){
		this.display = display;
		this.text = text;
	}
	
	
	public void run() {

		try {
			while (flag) {
				index++;
				if (!this.display.isDisposed()) {
					Runnable rannable = new Runnable() {

						public void run() {
							text.setText("index=" + index);
						}
					};
					
					display.asyncExec(rannable);
				}
				System.out.println(index);
				Thread.sleep(1000);
			}

		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println("我是线程,我执行完了~");

	}
	
	public void shoutDown() {
		this.flag = false;
	}
	
}

UI的东西

package com.yue.ui;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import com.cloudgarden.resource.SWTResourceManager;
import com.yue.thread.MyThread;


/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
public class NewSWTApp extends org.eclipse.swt.widgets.Composite {

	private Menu menu1;
	private Button stop;
	private Button start;
	private MenuItem aboutMenuItem;
	private MenuItem contentsMenuItem;
	private Menu helpMenu;
	private MenuItem helpMenuItem;
	private Text Infos;
	private MenuItem exitMenuItem;
	private MenuItem closeFileMenuItem;
	private MenuItem saveFileMenuItem;
	private MenuItem newFileMenuItem;
	private MenuItem openFileMenuItem;
	private Menu fileMenu;
	private MenuItem fileMenuItem;
	
	MyThread t = null;

	{
		//Register as a resource user - SWTResourceManager will
		//handle the obtaining and disposing of resources
		SWTResourceManager.registerResourceUser(this);
	}

	public NewSWTApp(Composite parent, int style) {
		super(parent, style);
		initGUI();
	}
	
	/**
	* Initializes the GUI.
	*/
	private void initGUI() {
		try {
			this.setSize(new org.eclipse.swt.graphics.Point(400,300));
			this.setBackground(SWTResourceManager.getColor(192, 192, 192));
			FormLayout thisLayout = new FormLayout();
			this.setLayout(thisLayout);
			this.addDisposeListener(new DisposeListener() {
				public void widgetDisposed(DisposeEvent evt) {
					thisWidgetDisposed(evt);
				}
			});
			{
				stop = new Button(this, SWT.PUSH | SWT.CENTER);
				FormData stopLData = new FormData();
				stopLData.width = 89;
				stopLData.height = 28;
				stopLData.left =  new FormAttachment(0, 1000, 282);
				stopLData.top =  new FormAttachment(0, 1000, 75);
				stop.setLayoutData(stopLData);
				stop.setText("stoop");
				stop.addMouseListener(new MouseAdapter() {
					public void mouseDown(MouseEvent evt) {
						stopMouseDown(evt);
					}
				});
			}
			{
				start = new Button(this, SWT.PUSH | SWT.CENTER);
				FormData startLData = new FormData();
				startLData.width = 89;
				startLData.height = 33;
				startLData.left =  new FormAttachment(0, 1000, 282);
				startLData.top =  new FormAttachment(0, 1000, 21);
				start.setLayoutData(startLData);
				start.setText("start");
				start.addMouseListener(new MouseAdapter() {
					public void mouseDown(MouseEvent evt) {
						startMouseDown(evt);
					}
				});
			}
			{
				Infos = new Text(this, SWT.MULTI | SWT.WRAP);
				FormData InfosLData = new FormData();
				InfosLData.width = 243;
				InfosLData.height = 113;
				InfosLData.left =  new FormAttachment(0, 1000, 19);
				InfosLData.top =  new FormAttachment(0, 1000, 21);
				Infos.setLayoutData(InfosLData);
				Infos.setText("Infos");
			}
			{
				menu1 = new Menu(getShell(), SWT.BAR);
				getShell().setMenuBar(menu1);
				{
					fileMenuItem = new MenuItem(menu1, SWT.CASCADE);
					fileMenuItem.setText("File");
					{
						fileMenu = new Menu(fileMenuItem);
						{
							openFileMenuItem = new MenuItem(fileMenu, SWT.CASCADE);
							openFileMenuItem.setText("Open");
						}
						{
							newFileMenuItem = new MenuItem(fileMenu, SWT.CASCADE);
							newFileMenuItem.setText("New");
						}
						{
							saveFileMenuItem = new MenuItem(fileMenu, SWT.CASCADE);
							saveFileMenuItem.setText("Save");
						}
						{
							closeFileMenuItem = new MenuItem(fileMenu, SWT.CASCADE);
							closeFileMenuItem.setText("Close");
						}
						{
							exitMenuItem = new MenuItem(fileMenu, SWT.CASCADE);
							exitMenuItem.setText("Exit");
						}
						fileMenuItem.setMenu(fileMenu);
					}
				}
				{
					helpMenuItem = new MenuItem(menu1, SWT.CASCADE);
					helpMenuItem.setText("Help");
					{
						helpMenu = new Menu(helpMenuItem);
						{
							contentsMenuItem = new MenuItem(helpMenu, SWT.CASCADE);
							contentsMenuItem.setText("Contents");
						}
						{
							aboutMenuItem = new MenuItem(helpMenu, SWT.CASCADE);
							aboutMenuItem.setText("About");
						}
						helpMenuItem.setMenu(helpMenu);
					}
				}
			}
			this.layout();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	* Auto-generated main method to display this 
	* org.eclipse.swt.widgets.Composite inside a new Shell.
	*/
	public static void main(String[] args) {
		Display display = Display.getDefault();
		Shell shell = new Shell(display);
		NewSWTApp inst = new NewSWTApp(shell, SWT.NULL);
		Point size = inst.getSize();
		shell.setLayout(new FillLayout());
		shell.layout();
		if(size.x == 0 && size.y == 0) {
			inst.pack();
			shell.pack();
		} else {
			Rectangle shellBounds = shell.computeTrim(0, 0, size.x, size.y);
			shell.setSize(shellBounds.width, shellBounds.height);
		}
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
	}
	
	//启动线程
	private void startMouseDown(MouseEvent evt) {
		System.out.println("start.mouseDown, event="+evt);
		this.t = new MyThread(Display.getDefault(),Infos);
		t.start();
	}
	
	//终止线程
	private void stopMouseDown(MouseEvent evt) {
		System.out.println("stop.mouseDown, event="+evt);
		this.t.shoutDown();
	}
	
	//销毁时终止线程
	private void thisWidgetDisposed(DisposeEvent evt) {
		System.out.println("我执行了终止操作    this.widgetDisposed, event="+evt);
		if(this.t.isAlive()){
			this.t.shoutDown();
		}
	}

}

myeclipse项目稍后奉上 例子 传送门



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值