Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

The Rich Get Richer: Eclipse Rich AJAX Platform Builds on RCP : Page 3

The new Eclipse Rich AJAX Platform (RAP) is a server-side platform that multiple concurrent users can access via their browsers and Eclipse RCP developers can learn in no time.


advertisement
Eclipse RAP Test Drive: A Simple ToDo List
This section walks you through writing a basic application to manage your ToDo lists with RAP. This sample will show how RAP stores user data are in different sessions, allowing for multiple concurrent users on the same application. (Refer to the downloadable source code for the full listings.)

Start by installing RAP. Be sure to follow the instructions shown on the RAP project site, as they contain some extra steps that you must take, such as defining the RAP target platform.

Next, start Eclipse and create a new plug-in project. Specify that you are not going to create an RCP application and choose "RAP application with a view" from the available RAP templates. When you complete the wizard, you will have a completely functional basic application. If you examine it closely, you will notice that it is 90 percent similar to an RCP application. The only difference is the application's starting point is org.eclipse.rwt.lifecycle.IentryPoint, as opposed to org.eclipse.equinox.app.Iapplication in the case of RCP.



Now modify the application to meet the sample application's needs. The ToDo items will have one of three possible statuses: incomplete, in progress, or complete. They all will be rendered as a list of push buttons. When a user clicks a button, the corresponding ToDo item moves from one status to the next. Therefore, define the Status enum as follows:

private enum Status { INCOMPLETE( PlatformUI.getWorkbench().getDisplay(). getSystemColor(SWT.COLOR_RED)) , IN_PROGRESS( PlatformUI.getWorkbench().getDisplay(). getSystemColor(SWT.COLOR_YELLOW)), COMPLETE( PlatformUI.getWorkbench().getDisplay(). getSystemColor(SWT.COLOR_GREEN)) ; private Color color ; private Status(Color color) { this.color = color ; } public Color getColor() { return color ; } }

Then redefine the createPartControl() method of the View created by the template as follows:

private Map<String, Status> list; public void createPartControl(Composite parent) { Composite contents = new Composite(parent, SWT.NONE); contents.setLayout(new GridLayout(1,false)); this.parent = contents; new Label(contents, SWT.NONE).setText("Add Todo:"); Composite inputComposite = new Composite(contents, SWT.NONE); inputComposite.setLayoutData( new GridData(GridData.FILL_HORIZONTAL)); inputComposite.setLayout(new GridLayout(2,false)); final Text inputText = new Text(inputComposite, SWT.BORDER); inputText.setLayoutData( new GridData(GridData.FILL_HORIZONTAL)); Button submit = new Button( inputComposite,SWT.PUSH | SWT.BORDER); submit.setText("Add!"); submit.setLayoutData(new GridData()); submit.addSelectionListener( new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) {} public void widgetSelected(SelectionEvent e) { System.out.println("Adding " + inputText.getText()); list.put(inputText.getText(),Status.INCOMPLETE); createTodos(); } }); new Label(contents, SWT.NONE).setText("Todo List:"); list = new HashMap<String,Status>(); createTodos(); }

Finally, define the createTodos() method that is responsible for drawing the single ToDo items as follows:

public void createTodos() { if (todos != null) todos.dispose(); todos = new Composite(parent,SWT.NONE); todos.setLayoutData(new GridData(GridData.FILL_BOTH)); todos.setLayout(new GridLayout(1,true)); for (Map.Entry<String, Status> entry: list.entrySet()) { System.out.println( "Adding button for " + entry.getKey() + "," + entry.getValue()); Button b= new Button(todos, SWT.NONE); b.setText(entry.getKey()); b.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); b.setBackground(entry.getValue().getColor()); b.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { Status status = list.get(((Button)e.widget).getText()); System.out.println("Status is " + status); Status next = null ; if (status.equals(Status.COMPLETE)) next = Status.INCOMPLETE; if (status.equals(Status.INCOMPLETE)) next = Status.IN_PROGRESS; if (status.equals(Status.IN_PROGRESS)) next = Status.COMPLETE; System.out.println("Next Status is " + next); list.put(((Button)e.widget).getText(),next); createTodos(); } public void widgetDefaultSelected(SelectionEvent e) {} }); } parent.pack(true); }

You can now run the application and test it with multiple concurrent browsers. As Figure 4 shows, each user has access only to his or her own ToDo list, without interfering with the others. You didn't have to implement anything specific for this to happen; RAP handles it all in the background with its session-management capabilities.

Click to enlarge

Figure 4. The ToDo List Application Accessed by Multiple Concurrent Browsers:
Each user has access only to his or her own ToDo list, without interfering with the others.

Another Eclipse RAP Test Drive: An Online Newsticker
The second RAP example for you to experiment with is a newsticker: a simple view that will display news items as soon as they are published, one per line (see Figure 5).

Click to enlarge

Figure 5. The Newsticker Sample Application:
Here's a simple view that displays news items as soon as they are published.

This example reveals another difference between RAP and RCP: server-side push events. RAP supports server-side generation of events, which updates the user interface and asynchronously pushes the events to the clients. You use the standard SWT method call Display.asyncexec() to dispatch such events, but you first have to inform RWT that you are going to use server-side generated events. You can do so using the org.eclipse.rwt.lifecycle.UICallback.activate() method (and its cousin UICallback.deactivate() when you're done).

This example focuses only on the code that triggers server-side events. The first thing you need to do is attach a listener to the button the user will click to start receiving events. The following listing shows an excerpt from the createPartControl() method of the application View, which performs just that:

Button b = new Button(actionBar, SWT.BORDER); b.setText("Activate!"); b.setLayoutData(new GridData()); b.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { UICallBack.activate("notifierId"); notifierThread = new Thread(createRunnable()); notifierThread.setDaemon(true); notifierThread.start(); } public void widgetDefaultSelected(SelectionEvent e) {} });

Note that the code relies on UICallBack.activate(), since it is going to generate server-side push events. The notifierThread thread fetches events, and its behavior is defined in the createRunnable() method, shown here:

private Runnable createRunnable() { return new Runnable() { public void run() { running = true; // volatile variable accessed also // from the outside of this method while (running) { // read news items from somewhere ... final String message = readNextNewsItem(); // it refers to the textarea which will // collect news items t.getDisplay().asyncExec(new Runnable(){ public void run() { t.append(new Date() + ": " + message + "\n"); } }); } // we're no longer generating events, so // we deactivate the UICallBack t.getDisplay().asyncExec(new Runnable() { public void run() { UICallBack.deactivate("notifierId"); } }); } }; }

Remember to always use Display.asyncExec() when dealing with the user interface, otherwise the program will either behave erratically or raise exceptions.

As you can see, pushing events is quite easy in a RAP application, thanks to the underlying support from the SWT core. You can use server-side push for online chats or progress bars for long-running operations as well.



Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap