Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Rich Client Platform (RCP) » Animating view icon - Invalid thread access exception(Animating view icon by new thread throws an exception. Please help.)
Animating view icon - Invalid thread access exception [message #494633] Sun, 01 November 2009 13:53 Go to next message
Honza Sk is currently offline Honza SkFriend
Messages: 1
Registered: November 2009
Junior Member
Hello,

I'm beginner in Eclipse and I would like to ask for help. In my application I want to include simple web browser as one of the views. I created a view etc. and it works fine.

Anyway I wanted to animate the view icon using a spinning wheel. I wrote the code the way that the animation runs in separate thread, unfortunatelly it throws exception Invalid thread access and I did not find out why and how to make it work.

If I call the animation directly from the main thread via ProgressListener (in the code below this is commented), it works fine, of course it does not rotate smoothly. Only when I call it from it's own thread, it does not work.

Can anybody help me? Thanks. Here is the code:

package info.honza.views.browser;

import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.TitleEvent;
import org.eclipse.swt.browser.TitleListener;
import org.eclipse.swt.browser.ProgressListener;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.part.ViewPart;
import java.text.DecimalFormat;

public class Browser extends ViewPart {

	public static final String ID = "info.honza.views.browser.browser";

	private static final String DEFAULT_HOMEPAGE_URL = "http://www.google.com/";
	private String homepageUrl = DEFAULT_HOMEPAGE_URL;
	
	private static final String FAVICON_DEFAULT = "/icons/browser/web.png";
	private static final String FAVICON_PROGRESS_PATTERN = "/icons/browser/wait%index%.png";
	private static final int FAVICON_PROGRESS_INDEX_MIN = 1;
	private static final int FAVICON_PROGRESS_INDEX_MAX = 12;
	private static final DecimalFormat FAVICON_PROGRESS_INDEX_FORMATTER = new DecimalFormat("00");
	private Integer faviconProgressIndex = FAVICON_PROGRESS_INDEX_MIN;
	private FaviconProgressAnimation faviconProgressAnimation = null;
	
	private org.eclipse.swt.browser.Browser browser;

	public Browser() {
	}

	public Browser(String homepageUrl) {
		this.homepageUrl = homepageUrl;
	}

	public boolean setUrl(String url) {
		//animateProgress();
		startProgressFaviconAnimation();
		return browser.setUrl(url);
	}
	
	@Override
	public void createPartControl(Composite parent) {
		browser = new org.eclipse.swt.browser.Browser(parent, SWT.NONE);
		hookTitleListener();
		hookProgressListener();
		this.setUrl(homepageUrl);
	}
	
	@Override
	public void setFocus() {
	}

	private void hookTitleListener() {
		browser.addTitleListener(new TitleListener() {
			public void changed(TitleEvent event) {
				setPartName(event.title);
			}
		});
	}
	
	private void hookProgressListener() {
		browser.addProgressListener(new ProgressListener() {
			public void changed(ProgressEvent event) {
				if (event.current != 0) {
					//animateProgress();
					startProgressFaviconAnimation();
				}
			}
			public void completed(ProgressEvent event) {
				setFaviconFromWebsite();
			}
		});
	}
	
	private void setFaviconFromWebsite() {
		stopProgressFaviconAnimation();
		//setTitleImage(ImageDescriptor.createFromFile(getClass(), FAVICON_DEFAULT).createImage());
	}

	private void setFaviconProgress() {
		setTitleImage(ImageDescriptor.createFromFile(getClass(), FAVICON_PROGRESS_PATTERN.replace("%index%", FAVICON_PROGRESS_INDEX_FORMATTER.format(faviconProgressIndex))).createImage());
	}
	
	private void startProgressFaviconAnimation() {
		if (faviconProgressAnimation == null) {
			faviconProgressAnimation = new FaviconProgressAnimation();
			faviconProgressAnimation.start();
		}
	}
	
	private void stopProgressFaviconAnimation() {
		if (faviconProgressAnimation != null) {
			faviconProgressAnimation = null;
		}
	}
	
	protected void animateProgress() {
		setTitleImage(ImageDescriptor.createFromFile(getClass(), FAVICON_PROGRESS_PATTERN.replace("%index%", FAVICON_PROGRESS_INDEX_FORMATTER.format(faviconProgressIndex))).createImage());
		faviconProgressIndex = (faviconProgressIndex == FAVICON_PROGRESS_INDEX_MAX) ? FAVICON_PROGRESS_INDEX_MIN : faviconProgressIndex + 1;
	}
	
	public class FaviconProgressAnimation extends Thread {
		public void run() {
			while (true) {
				try {
					animateProgress();
					Thread.sleep(1000);
				} catch (InterruptedException e) {
	            }
			}
		}
	}
}


This throws exception:
org.eclipse.swt.SWTException: Invalid thread access
	at org.eclipse.swt.SWT.error(SWT.java:3884)
	at org.eclipse.swt.SWT.error(SWT.java:3799)
	at org.eclipse.swt.SWT.error(SWT.java:3770)
	at org.eclipse.swt.widgets.Widget.error(Widget.java:463)
	at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:355)
	at org.eclipse.swt.widgets.Widget.getData(Widget.java:521)
	at org.eclipse.ui.internal.presentations.defaultpresentation.DefaultTabFolder.getTab(DefaultTabFolder.java:185)
	at org.eclipse.ui.internal.presentations.defaultpresentation.DefaultTabFolder.getItems(DefaultTabFolder.java:237)
	at org.eclipse.ui.internal.presentations.util.AbstractTabFolder.findItem(AbstractTabFolder.java:172)
	at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.getTab(PresentablePartFolder.java:375)
	at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.childPropertyChanged(PresentablePartFolder.java:304)
	at org.eclipse.ui.internal.presentations.util.PresentablePartFolder.access$2(PresentablePartFolder.java:303)
	at org.eclipse.ui.internal.presentations.util.PresentablePartFolder$3.propertyChanged(PresentablePartFolder.java:83)
	at org.eclipse.ui.internal.presentations.PresentablePart.firePropertyChange(PresentablePart.java:137)
	at org.eclipse.ui.internal.presentations.PresentablePart$1.propertyChanged(PresentablePart.java:97)
	at org.eclipse.ui.internal.PartPane.firePropertyChange(PartPane.java:620)
	at org.eclipse.ui.internal.PartPane.propertyChanged(PartPane.java:625)
	at org.eclipse.ui.internal.WorkbenchPartReference.immediateFirePropertyChange(WorkbenchPartReference.java:571)
	at org.eclipse.ui.internal.WorkbenchPartReference.setImageDescriptor(WorkbenchPartReference.java:265)
	at org.eclipse.ui.internal.WorkbenchPartReference.refreshFromPart(WorkbenchPartReference.java:326)
	at org.eclipse.ui.internal.WorkbenchPartReference.partPropertyChanged(WorkbenchPartReference.java:296)
	at org.eclipse.ui.internal.WorkbenchPartReference$2.propertyChanged(WorkbenchPartReference.java:181)
	at org.eclipse.ui.part.WorkbenchPart.firePropertyChange(WorkbenchPart.java:129)
	at org.eclipse.ui.part.WorkbenchPart.setTitleImage(WorkbenchPart.java:326)
	at info.honza.views.browser.Browser.animateProgress(Browser.java:100)
	at info.honza.views.browser.Browser$FaviconProgressAnimation.run(Browser.java:108)


Thanks for any answers or advices. Take care,

Honza
Re: Animating view icon - Invalid thread access exception [message #494634 is a reply to message #494633] Sun, 01 November 2009 14:20 Go to previous message
Wim Jongman is currently offline Wim JongmanFriend
Messages: 418
Registered: July 2009
Senior Member
Hi Honza,

Updates to the UI must be done in the user interface thread. To run code in
the user interface thread from another thread you must use one of the exec
methods in the Display class.

Make sure to only execute small portions of your animation otherwise you will
lockup the UI. E.g. the next code will lockup the UI

Runnable runner = new Runnable(){
p v run(){
while(pageIsLoading())
animateOneCycle();
}
}
Display.getCurrent().syncExec(runner);

The following code will only add small portions of code at a time to the UI
thread

Runnable runner = new Runnable(){
p v run(){
animateOneCycle();
}
}

while(pageIsLoading())
Display.getCurrent().syncExec(runner);

Best regards,

Wim


> Hello,
>
> I'm beginner in Eclipse and I would like to ask for help. In my application
I want to include simple web browser as one of the views. I created a view
etc. and it works fine.
>
> Anyway I wanted to animate the view icon using a spinning wheel. I wrote
the code the way that the animation runs in separate thread, unfortunatelly
it throws exception Invalid thread access and I did not find out why and how
to make it work.
>
> If I call the animation directly from the main thread via ProgressListener
(in the code below this is commented), it works fine, of course it does not
rotate smoothly. Only when I call it from it's own thread, it does not work.
>
> Can anybody help me? Thanks. Here is the code:
>
>
> package info.honza.views.browser;
>
> import org.eclipse.swt.SWT;
> import org.eclipse.swt.browser.TitleEvent;
> import org.eclipse.swt.browser.TitleListener;
> import org.eclipse.swt.browser.ProgressListener;
> import org.eclipse.swt.browser.ProgressEvent;
> import org.eclipse.swt.widgets.Composite;
> import org.eclipse.jface.resource.ImageDescriptor;
> import org.eclipse.ui.part.ViewPart;
> import java.text.DecimalFormat;
>
> public class Browser extends ViewPart {
>
> public static final String ID = "info.honza.views.browser.browser";
>
> private static final String DEFAULT_HOMEPAGE_URL =
"http://www.google.com/";
> private String homepageUrl = DEFAULT_HOMEPAGE_URL;
>
> private static final String FAVICON_DEFAULT = "/icons/browser/web.png";
> private static final String FAVICON_PROGRESS_PATTERN =
"/icons/browser/wait%index%.png";
> private static final int FAVICON_PROGRESS_INDEX_MIN = 1;
> private static final int FAVICON_PROGRESS_INDEX_MAX = 12;
> private static final DecimalFormat FAVICON_PROGRESS_INDEX_FORMATTER = new
DecimalFormat("00");
> private Integer faviconProgressIndex = FAVICON_PROGRESS_INDEX_MIN;
> private FaviconProgressAnimation faviconProgressAnimation = null;
>
> private org.eclipse.swt.browser.Browser browser;
>
> public Browser() {
> }
>
> public Browser(String homepageUrl) {
> this.homepageUrl = homepageUrl;
> }
>
> public boolean setUrl(String url) {
> //animateProgress();
> startProgressFaviconAnimation();
> return browser.setUrl(url);
> }
>
> @Override
> public void createPartControl(Composite parent) {
> browser = new org.eclipse.swt.browser.Browser(parent, SWT.NONE);
> hookTitleListener();
> hookProgressListener();
> this.setUrl(homepageUrl);
> }
>
> @Override
> public void setFocus() {
> }
>
> private void hookTitleListener() {
> browser.addTitleListener(new TitleListener() {
> public void changed(TitleEvent event) {
> setPartName(event.title);
> }
> });
> }
>
> private void hookProgressListener() {
> browser.addProgressListener(new ProgressListener() {
> public void changed(ProgressEvent event) {
> if (event.current != 0) {
> //animateProgress();
> startProgressFaviconAnimation();
> }
> }
> public void completed(ProgressEvent event) {
> setFaviconFromWebsite();
> }
> });
> }
>
> private void setFaviconFromWebsite() {
> stopProgressFaviconAnimation();
> //setTitleImage(ImageDescriptor.createFromFile(getClass(),
FAVICON_DEFAULT).createImage());
> }
>
> private void setFaviconProgress() {
> setTitleImage(ImageDescriptor.createFromFile(getClass(),
FAVICON_PROGRESS_PATTERN.replace("%index%",
FAVICON_PROGRESS_INDEX_FORMATTER.format(faviconProgressIndex ))).createImage());
> }
>
> private void startProgressFaviconAnimation() {
> if (faviconProgressAnimation == null) {
> faviconProgressAnimation = new FaviconProgressAnimation();
> faviconProgressAnimation.start();
> }
> }
>
> private void stopProgressFaviconAnimation() {
> if (faviconProgressAnimation != null) {
> faviconProgressAnimation = null;
> }
> }
>
> protected void animateProgress() {
> setTitleImage(ImageDescriptor.createFromFile(getClass(),
FAVICON_PROGRESS_PATTERN.replace("%index%",
FAVICON_PROGRESS_INDEX_FORMATTER.format(faviconProgressIndex ))).createImage());
> faviconProgressIndex = (faviconProgressIndex == FAVICON_PROGRESS_INDEX_MAX)
? FAVICON_PROGRESS_INDEX_MIN : faviconProgressIndex + 1;
> }
>
> public class FaviconProgressAnimation extends Thread {
> public void run() {
> while (true) {
> try {
> animateProgress();
> Thread.sleep(1000);
> } catch (InterruptedException e) {
> }
> }
> }
> }
> }
>
>
> This throws exception:
> org.eclipse.swt.SWTException: Invalid thread access
> at org.eclipse.swt.SWT.error(SWT.java:3884)
> at org.eclipse.swt.SWT.error(SWT.java:3799)
> at org.eclipse.swt.SWT.error(SWT.java:3770)
> at org.eclipse.swt.widgets.Widget.error(Widget.java:463)
> at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:355)
> at org.eclipse.swt.widgets.Widget.getData(Widget.java:521)
> at
org.eclipse.ui.internal.presentations.defaultpresentation.De faultTabFolder.getTab(DefaultTabFolder.java:185)
> at
org.eclipse.ui.internal.presentations.defaultpresentation.De faultTabFolder.getItems(DefaultTabFolder.java:237)
> at
org.eclipse.ui.internal.presentations.util.AbstractTabFolder .findItem(AbstractTabFolder.java:172)
> at
org.eclipse.ui.internal.presentations.util.PresentablePartFo lder.getTab(PresentablePartFolder.java:375)
> at
org.eclipse.ui.internal.presentations.util.PresentablePartFo lder.childPropertyChanged(PresentablePartFolder.java:304)
> at
org.eclipse.ui.internal.presentations.util.PresentablePartFo lder.access$2(PresentablePartFolder.java:303)
> at
org.eclipse.ui.internal.presentations.util.PresentablePartFo lder$3.propertyChanged(PresentablePartFolder.java:83)
> at
org.eclipse.ui.internal.presentations.PresentablePart.firePr opertyChange(PresentablePart.java:137)
> at
org.eclipse.ui.internal.presentations.PresentablePart$1.prop ertyChanged(PresentablePart.java:97)
> at org.eclipse.ui.internal.PartPane.firePropertyChange(PartPane .java:620)
> at org.eclipse.ui.internal.PartPane.propertyChanged(PartPane.ja va:625)
> at
org.eclipse.ui.internal.WorkbenchPartReference.immediateFire PropertyChange(WorkbenchPartReference.java:571)
> at
org.eclipse.ui.internal.WorkbenchPartReference.setImageDescr iptor(WorkbenchPartReference.java:265)
> at
org.eclipse.ui.internal.WorkbenchPartReference.refreshFromPa rt(WorkbenchPartReference.java:326)
> at
org.eclipse.ui.internal.WorkbenchPartReference.partPropertyC hanged(WorkbenchPartReference.java:296)
> at
org.eclipse.ui.internal.WorkbenchPartReference$2.propertyCha nged(WorkbenchPartReference.java:181)
> at
org.eclipse.ui.part.WorkbenchPart.firePropertyChange(Workben chPart.java:129)
> at org.eclipse.ui.part.WorkbenchPart.setTitleImage(WorkbenchPar t.java:326)
> at info.honza.views.browser.Browser.animateProgress(Browser.jav a:100)
> at
info.honza.views.browser.Browser$FaviconProgressAnimation.ru n(Browser.java:108)
>
> Thanks for any answers or advices. Take care,
>
> Honza
Previous Topic:Eclipse Training Series
Next Topic:Performance of RCP
Goto Forum:
  


Current Time: Sat Nov 29 00:40:12 GMT 2014

Powered by FUDForum. Page generated in 0.01570 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software