Welcome to our active community of Eclipse RCP developers! Visit the tutorials Table of Contents or search for the topics you need help with. Then return the favor by contributing your own tip or trick. Don't hesitate, get sharing right away. It's easy!

Saturday, April 4, 2009

Updating a Widget in an Eclipse RCP Application from a Worker Thread

This article shows how to update an Eclipse RCP Application widget from a worker thread and builds off of a clean RCP Application with a View. When programming GUI applications, it's often necessary to run a background processes to do some calculations or coordinate timed events. If these processes run on the main (GUI) thread, the GUI will be unresponsive to users' clicks during the process, leading to a bad user experience. To get around this problem, worker threads can be created to do the processing, leaving the GUI thread responsive to user input. The catch though is that you can't update any GUI components (SWT or JFace widgets in this case) from the worker thread. If you try to you get an exception such as: Exception in thread "Thread-3" org.eclipse.swt.SWTException: Invalid thread access. And worse, the compiler won't warn you of this pitfall. In this tutorial an Eclipse RCP application with a view is created, and a label is updated every second from a worker thread.

Step 0: Create a Hello World Eclipse RCP Application and add a View to it.

Step 1: Create a worker thread class. The following class called WorkerThread implements Runnable and is passed a reference to the MainView class. In its run method, which must be implemented, a counter is initialized to zero and is incremented by one followed by a one second pause. Right before the incrementation the updateLabelText method in the MainView is called. A go() method is added to the class to create the thread and call the run method.


package com.eclipsercptutorials.workerthread;

class WorkerThread implements Runnable{

// The timer interval in milliseconds
private static final int TIMER_INTERVAL = 1000;

private MainView mainView;

public WorkerThread(MainView mainView){
this.mainView = mainView;
}

public void go(){

Thread t = new Thread(this);
t.start();

}

public void run() {
int counter = 0;
try {
while(mainView != null){
mainView.updateLabelText("Counter = " + counter);
counter++;
Thread.sleep(TIMER_INTERVAL);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

Step 2: Add a label to the MainView and start the worker thread in the createPartControl method.

public void createPartControl(Composite parent) {

label = new Label(parent, SWT.None); //new up a Label widget
WorkerThread workerThread = new WorkerThread(this);
workerThread.go();
}

Step 3: Add a method in the MainView class that updates the label's text and is called by the worker thread. The method called updateLabelText in MainView uses the Display's asyncExec method to post a Runnable that is executed in the main thread enabling the update of the Label widget from the worker thread. In the Runnable's run method make sure the widget isn't null or disposed first.

package com.eclipsercptutorials.workerthread;

import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.part.ViewPart;

public class MainView extends ViewPart {

public static final String ID = "com.eclipsercptutorials.workerThread.mainView"; // the ID needs to match the id set in the view's properties

public Label label;

public MainView() {}

public void createPartControl(Composite parent) {

label = new Label(parent, SWT.None); //new up a Label widget
WorkerThread workerThread = new WorkerThread(this);
workerThread.go();
}

public void setFocus() {}

public void updateLabelText(final String labelText){

try{
Display.getDefault().asyncExec(new Runnable(){
public void run(){
if(!label.isDisposed() && label !=null){
label.setText(labelText);
}
}
});
}catch(SWTException e){
//eat it!
}
}
}


Step 3: Run the application and test if everything worked. Your application should now have a label in the view that updates its value each second and look something like this:
Piece of cake!!

Get the code: com.eclipsercptutorials.workerThread.zip
<--- Previous - Add an Image to an Eclipse RCP Application
---> Next - Animation in Eclipse RCP Applications - A Bouncing Ball
Also see: Eclipse RCP Tutorial Table of Contents


If you enjoyed this post, make sure you subscribe to the Eclipse RCP Tutorials RSS feed to receive new posts in a reader or via email!

1 comments:

vuk said...

Wonderful starter snippet on this subject! Thanks!

Post a Comment

Wanted: your Eclipse RCP tips and tricks. We created this website as a place to give back to the Eclipse open source community by offering people help in developing their own Rich Client Platform (RCP) applications. We hope you find value in the tutorials found here. Visit the share page for information on how to contribute a unique RCP Application tutorial or code snippet and give back to the community! The style of the tutorials are designed to be quick and easy to create by contributors and to understand by the people learning from them. Import the RCP projects found at the end of the tutorials and export your contributed projects as shown in Import and Export an Eclipse RCP Application Project.


Enter your email address to automatically
receive the newest articles:

 

Eclipse RCP Tutorials - beta Copyright © 2009