这两天闲来无聊,做了一个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项目稍后奉上 例子 传送门