这两天闲来无聊,做了一个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; } }
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(); } } }