Skip to main content

Developing embedded applications with eJFace

eJFace makes developing applications on handheld devices fast and efficient

Sam Lo (locl@tw.ibm.com), Software Engineer, IBM
Sam Lo
Sam Lo is a software developer at the IBM China Software Development Lab and works in Lotus client technology concurrently. He loves to travel, play musical instruments, and follow sports. He is a Houston Rockets and Detroit Tigers fan, which explains the sports-related examples in this article.
Eric Hsu (mfhsu@tw.ibm.com), Software Engineer, IBM
Eric Hsu
Eric Hsu is a software developer at the IBM China Software Development Lab in Taipei. He works in Lotus Expediter client technology and Eclipse eRCP project development. He is a committer to the Eclipse eRCP project, as well.

Summary:  It is safe to assume the demand for applications on mobile devices will increase in coming years. Now is a good time to learn eJFace — the open-standards, embedded JFace library — a new technology to build embedded applications. Embedded JFace (eJFace) is a component of the embedded Rich Client Platform (eRCP), which provides an embedded environment for developers to compose user interfaces for embedded applications. Here, we compare eJFace to JFace and show how to develop applications with eJFace.

Date:  11 Sep 2007
Level:  Intermediate
Activity:  1948 views

eJFace consists of libraries that allow you to build applications without complex eSWT programming. It provides powerful APIs and introduces a Model-View-Controller (MVC) architecture for implementing and maintaining embedded applications painlessly. In this article, we explain how to develop applications with eJFace, and compare eJFace to JFace. This article will help developers who know JFace understand the differences between eJFace and JFace, and reduce the time needed to develop eJFace applications.

You will learn:

  • The structure of the eJFace library, its APIs, and their use
  • The differences between JFace and eJFace
  • How to develop an eJFace, eSWT, and eWorkbench application within an eRCP environment
  • How to add eJFace functionality to an application

In a nutshell

Let's start by briefly answering the three big questions developers ask when initially looking at eJFace.

1. What is eJFace?

  • eJFace is designed for handheld devices and is a pure subset of the desktop JFace library.
  • A platform-independent user interface API that extends and interoperates with the eSWT.
  • Integrates some eSWT widgets to provide many useful functionalities, such as MVC-based viewers, which reduces development and maintenance.
  • Excludes parts of the JFace library too bulky to offer a benefit on a handheld device.

2. What is eJFace used for?

  • The library provides advanced UI capabilities useful on embedded devices.
  • Makes eRCP applications that integrate with an eWorkbench.
  • Provides a set of classes that extends eSWT to enable eRCP applications to integrate with an eRCP workbench and provides more complex widgets, such as MVC-oriented viewers.

3. What are the characteristics of eJFace?

  • The relationship between eSWT and eJFace is the same as SWT and JFace.
  • eJFace is dependent on the Core and Expanded partitions of eSWT and the Java 2, Micro Edition (J2ME) Connected Device Configuration (CDC) profile.
  • It wraps eSWT widget in the context of the MVC paradigm in viewer. It hides many implementation details and reduces the number of lines of code.
  • It is built on top of eSWT and does not need additional native libraries to run.
  • It provides a resource-handling class that allows efficient manipulation of resources to conserve memory and boost performance.

eJFace package and details


Table 1. The supported packages in eJFace
Packages
org.eclipse.jface.actionSupport for shared UI resources, such as menus, tool bars, and status lines
org.eclipse.jface.operationJFace support for long-running operations
org.eclipse.jface.preferenceFramework for preferences
org.eclipse.jface.resourceSupports managing resources such as SWT fonts and images
org.eclipse.jface.utilBuilding blocks used throughout JFace, including property change events, a listener list implementation, and run-time checked assertions
org.eclipse.jface.viewersFramework for viewers, which are model-based content adapters for SWT widgets

As mentioned, eJFace removes significant packages and libraries of JFace, which are desktop-oriented and inappropriate for handheld devices. With the small footprint consideration and implementation complexity reduction in mind, eJFace provides the packages shown above. For further information about the APIs of each package, refer to the eJFace Java doc (see Resources).

Following is a summary of the packages mentioned in Table 1.

org.eclipse.jface.action
The org.eclipse.jface.action package is used to interact with users by responding to their actions. org.eclipse.jface.action package supports the contribution of items to the status line only. However, the Action package is recommended for use with the eSWT command widget because a command widget is easier to use. Select which dynamic menu appears while the attached widget has focus. See the example command widget provided in a sample application for more information.
org.eclipse.jface.operation
eJface drops almost all functionality from the JFace org.eclipse.jface.operation package, except for the IRunnableWithProgress interface. The IRunnableWithProgress interface is intended to be implemented by classes that perform long-running operations. Long-running operations are usually displayed by a modal dialog showing a progress indicator, along with a Cancel button or a progress bar.
org.eclipse.jface.preference
org.eclipse.jface.preference provides PreferencePage and PreferenceStore libraries only. PreferencePage is a single-use resource for a temporary dialog that shows a message or requests limited information. PreferencePage blocks other eRCP applications until PreferencePage is closed, which ensures that information is gathered before the main program executes. PreferenceStore is used to keep information for your application. PreferenceStore generates a property file to help the application store some useful information. PreferencePage, along with PreferenceStore, are often used to keep permanent information gleaned from user input. The PreferencePage sample application shows how to implement a prompt to gather user information and store content.
org.eclipse.jface.resource
As its name implies, org.eclipse.jface.resource package manages resources, such as image, color, and font information. It allows you to find specific resources easily. Also:
  • ImageRegistry and ImageDescriptor libraries maintain a mapping between symbolic color names and SWT colors. The supported image format is platform-dependent.
  • JFaceColors is used to get and store a device's default colors.
  • FontRegistry and FontDescriptor are used to maintain a mapping between symbolic font names and SWT fonts.
  • CompositeImageDescriptor is an abstract class for image descriptors that synthesize an image from other images in order to simulate the effect of a custom drawing.
  • JFaceResources are utility methods to access eJFace-specific resources.
  • StringConverter converts various data types to and from strings easily.
org.eclipse.jface.util
org.eclipse.jface.util provides useful methods to enhance eSWT usage, including property change events, an event listener collection mechanism, and run-time assertion checks.
org.eclipse.jface.viewers
org.eclipse.jface.viewers includes TreeViewer and TableViewer only. These viewers are based on the MVC architecture to separate inner functionalities from the look and feel. This allows eJFace viewers to be easily maintainable and expandable. Also:
  • TreeViewer is implemented by the eSWT tree widget to display hierarchical data for users to expand and collapse nodes and child nodes.
    • After constructing the TreeViewer, you must determine what its content is by implementing the ITreeContentProvider interface.
    • Determine how to display the content by implementing the ILabelProvider interface.
    • Pass it to the root node of your data by using the specified content and label providers.
  • TableViewer is implemented by the eSWT table widget to display data in columns and rows. Table and TableItem can be used to achieve what TableViewer can do.
    • Like TreeViewer, you create TableViewer first, then set the content provider accordingly.
    • Set the label provider.
    • Set the input.
The eJFace org.eclipse.jface.viewers demo application in Downloads shows how to implement TreeViewer and TableViewer.

Differences between eJFace and JFace

As mentioned, eJFace is a strict subset of JFace. Some libraries less likely to be used on embedded devices are removed or reduced considerably. Table 2 summarizes the major differences between eJFace and JFace.


Table 2. eJFace and JFace differences
eJFace and JFace compared
Packages removed from JFaceorg.eclipse.jface.dialogs
org.eclipse.jface.operation (eJFace provides the IRunnableWithProgress interface only)
org.eclipse.jface.window
org.eclipse.jface.wizard
Packages reduced from JFaceorg.eclipse.jface.action
org.eclipse.jface.preference (eJFace provides the PreferencePage class only)
org.eclipse.jface.viewers (eJFace provides TreeViewer and TableViewer only)
Unchanged packagesorg.eclipse.jface.resource
org.eclipse.jface.util

You might wonder why jface.wizard, jface.dialogs, and jface.window were removed from JFace. There are two reasons. First, the existing dialog, wizard, and window code is desktop-oriented and would not be appropriate for mobile use without significant rework. For example, dialogs on a cell phone typically should not use push buttons since a cell phone probably doesn't have a cursor and mouse. Second, the selected packages are more convenient functions that could easily be implemented by an application, rather than intricate or very common code.

You might also wonder why eJFace code does not use the command class within the eSWT Mobile Extensions. We would prefer not to have an eJFace dependency on Mobile Extensions since this is supposed to be an optional component within eRCP. Also, Mobile Extensions provides QueryDialog and TimedMessageBox, which replaces some of JFace dialogs with mobile-appropriate versions.

The changes to org.eclipse.jface.action require an explanation. JFace supports the contribution of items to the status line only. Since eWorkbench does not provide a common menu-bar function, most action classes are removed from eJFace. Nevertheless, action items are replaced with the command class in Mobile Extensions in eSWT.


eJFace org.eclipse.jface.viewers demo application

eJFace only provides a TreeViewer and a TableViewer. See Resources to learn how to develop the eWorkbench application.

TreeViewer

To design a TreeViewer demo application, you must create your node class as your data model. Here, we create two node classes named NBATeamNode and NBAPlayer. Next, you must define the relationship between your nodes. For example, NBATeamNode can add another NBATeamNode or NBAPlayer instance. You must define two separate ArrayLists in NBATeamNode to add them.


Listing 1. Define your node class and their parent-child relationship
                
public class NBATeamNode {
  private String name;
  private ArrayList teams   = new ArrayList();
  private ArrayList players = new ArrayList();
  private NBATeamNode parent;

  public NBATeamNode(String n){
    name = n;
  }
  protected Object getParent(){
    return parent;
  }
  public NBATeamNode addTeam(NBATeamNode child){
    teams.add(child);
    child.parent = this;
    return this;
  }
  public NBATeamNode addPlayer(NBAPlayer child){
    players.add(child);
    child.parent = this;
    return this;
  }
  public ArrayList getteams(){
    return teams;
  }
  public ArrayList getplayers(){
    return players;
  }
  public String toString(){
    return name;
  }

public class NBAPlayer {
  private String name;
  NBATeamNode parent;

  public NBAPlayer(String n){
    name = n;
  }
  protected Object getParent(){
    return parent;
  }
  public String toString(){
    return name;
  }

After extending org.eclipse.ercp.eworkbench.applications, we create a TreeViewer instance and associate with the current composite in createPartControl methods in the generated SampleView class. Then we set the desired layout of this tree and add the tree content provider and tree label provider instance to this TreeViewer. The content provider provides the parent-child relationship of all tree, while label provider provides the image and text represented by each element. Finally, give this TreeViewer an input node. Remember that this input should be the root node of your data model. For example, we create the root node first and add three NBATeamNodes to it as a different team name. Then we add five starter NBA players using the variable NBAPlayer to each team. As you can see, we input the root NBATeamNode named "root" into TreeViewer.


Listing 2. SampleView class
                
public void createPartControl(Composite parent){
  composite= new Composite(parent,SWT.NONE);
  composite.setLayout(new GridLayout(1,false));
		
  treeviewer = new TreeViewer(composite);		
  treeviewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
  treeviewer.setContentProvider(new SampleTreeContentProvider());
  treeviewer.setLabelProvider(new SampleTreeLabelProvider());
  treeviewer.setInput(getInput());
  treeviewer.expandAll();
}
	
private NBATeamNode getInput(){
  NBATeamNode root = new NBATeamNode("root");
  NBATeamNode team1= new NBATeamNode("Houston Rockets"); 
  NBATeamNode team2= new NBATeamNode("LA Lakers");
  ...
		
  root.addTeam(team1);
  root.addTeam(team2);
  ...
		
  team1.addPlayer(new NBAPlayer("Yao Ming"));
  team1.addPlayer(new NBAPlayer("Tracy McGrady"));
  ...
  		
  return root;
}

The tree content provider must implement ITreeContentProvider. Define the parent-child relationship of this tree using the getParent and getChildren methods. Finally, get the subelement of each element using getElements methods.


Listing 3. TreeViewerContentProvider
                
public class SampleTreeContentProvider implements ITreeContentProvider {
  //other methods are not mentioned here are unchanged
  public Object[] getChildren(Object arg0) {
    if(arg0 instanceof NBATeamNode) {
       NBATeamNode node = (NBATeamNode)arg0;
       return concat(node.getteams().toArray(),node.getplayers().toArray());
    }
    return EMPTY_ARRAY;
  }
  protected Object[] concat(Object[] object, Object[] more) {
    Object[] both = new Object[object.length + more.length];
    System.arraycopy(object, 0, both, 0, object.length);
    System.arraycopy(more, 0, both, object.length, more.length);	
    return both;
  }
  public Object getParent(Object arg0) {
    return ((NBATeamNode) arg0).getParent();
  }
  public Object[] getElements(Object arg0) {
		return getChildren(arg0);
  }
       

The tree label provider must implement ILabelProvider. As you can see, we define the image and text represented by each node using the getImage and getText methods.


Listing 4. TreeViewerLabelProvider
                
public class SampleTreeLabelProvider implements ILabelProvider {
  //other methods are not mentioned here are unchanged
  private ArrayList listeners;
  private Image Team, Player;

  public SampleTreeLabelProvider(){
    listeners = new ArrayList();
    Team  = new Image(null, getClass().getResourceAsStream("/res/file.png"));
    Player= new Image(null, getClass().getResourceAsStream("/res/folder.png"));
  }
  public Image getImage(Object arg0) {
    if(arg0 instanceof NBATeamNode){
       return Team;
    }else{
       return Player;
    }
  }
  public String getText(Object arg0) {		
    if(arg0 instanceof NBATeamNode) {
       return ((NBATeamNode)arg0).toString();
    }else{
       return ((NBAPlayer)arg0).toString();
    }
  }
  public void dispose() {
    if(Team  != null) Team  .dispose();
    if(Player != null) Player.dispose();
  }
}

After you deploy this demo application into the eWorkbench on a device, you will see the icon shown in the application list named Test TreeViewer Sample. Click Open in the command window to launch it. There, you will find the tree we created. You can expand each team and see the corresponding players on the teams' rosters.


Figure 1. TreeViewer demo application in eWorkbench on a device
TreeViewer demo application in eWorkbench on a device

TableViewer

To design a TableViewer demo application, you must create a data model class. Here, we create Book.java. As you can see, there are five properties to be printed in the table column. As a result, you must use the getter-setter method for each property for future use.


Listing 5. Define your data model class
                
public class Book {
  String name;
  String isbn;
  String publisheddate;
  String price;
  String available;
  
  public String getAvailable() {
    return available;
  }
  public void setAvailable(String available) {
    this.available = available;
  }
  public String getIsbn() {
    return isbn;
  }
  public void setIsbn(String isbn) {
    this.isbn = isbn;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getPrice() {
    return price;
  }
  public void setPrice(String price) {
    this.price = price;
  }
  public String getPublisheddate() {
    return publisheddate;
  }
  public void setPublisheddate(String publisheddate) {
    this.publisheddate = publisheddate;
  }
}

After extending org.eclipse.ercp.eworkbench.applications, we create a TableViewer instance and associate it with the current composite createPartControl methods in the SampleView class. Then we set the desired layout. But before adding a content provider and label provider instance to this table viewer, we must first create our table. The table includes the appropriate number of columns and a corresponding name. Pack each column and make it visible on your table. Finally, set table content provider and table label provider and give this TableViewer input. (In other words, feed it data.) Remember that this input should be the ArrayList of your data model. For example, we create the ArrayList first and add three book instances to it. The value of the fields in the table will be set according to your content provider and label provider classes.


Listing 6. SampleView class
                
public void createPartControl(Composite parent) {
  composite= new Composite(parent,SWT.NONE);
  composite.setLayout(new GridLayout(1,false));
			
  tableviewer = new TableViewer(composite);	
  Table table = tableviewer.getTable();
  table.setLayoutData(new GridData(GridData.FILL_BOTH));
  column0 = new TableColumn(table,SWT.LEFT,0);
  column0.setText("Books Name");
  column1 = new TableColumn(table,SWT.LEFT,1);
  column1.setText("ISBN");
  column2 = new TableColumn(table,SWT.LEFT,2);
  column2.setText("Published Date");
  column3 = new TableColumn(table,SWT.LEFT,3);
  column3.setText("Price");
  column4 = new TableColumn(table,SWT.LEFT,4);
  column4.setText("Available Now?");
		
  for(int i =0, n=table.getColumnCount();i<n;i++){
      table.getColumn(i).pack();
  }
		
  table.setHeaderVisible(true);
  table.setLinesVisible(true);
		
  tableviewer.setContentProvider(new SampleTableContentProvider());
  tableviewer.setLabelProvider(  new SampleTableLabelProvider());
  tableviewer.setInput(getInput());
}

private ArrayList getInput() {
  Book b1 = new Book();
  Book b2 = new Book();
  Book b3 = new Book();
		
  b1.setName("Red Book");
  b1.setIsbn("U2w3e4r5t6y");
  b1.setPublisheddate("1980-08-28");
  b1.setPrice("$1000");
  b1.setAvailable("Yes");
		
  b2.setName("Blue Book");
  b2.setIsbn("U1q2w3e4r");
  ...	
  return Books;
}

TableViewerContentProvider must implement the IStructuredContentProvider interface. TableViewerContentProvider defines the display relationship of this table. As you can see in this class, we can get each data of one specific array, which may represent book name or price, using the getElements method.


Listing 7. TableViewerContentProvider
                
public class SampleTableContentProvider implements IStructuredContentProvider {
  //other methods are not mentioned here are unchanged
  public Object[] getElements(Object arg0) {
    return ((ArrayList)arg0).toArray();
  }
}

TableViewerLabelProvider must implement the ITableLabelProvider interface. TableViewerLabelProvider defines the text or image of each column in this table. We can get the text of each element using the getColumnText method. (Here, we did not implement the getColumnImage method.)


Listing 8. TableViewerLabelProvider
                
public class SampleTableLabelProvider implements ITableLabelProvider {
  //other methods are not mentioned here are unchanged
  public Image getColumnImage(Object arg0, int arg1) {
    return null;
  }
  public String getColumnText(Object arg0, int arg1) {
    String result = "";
    Book book = (Book) arg0;
    switch(arg1){
      case 0:
        result =  book.getName();
	break;
      case 1:	
	result =  book.getIsbn();
	break;
      case 2:
	result =  book.getPublisheddate();
	break;
      case 3:
	result =  book.getPrice();
	break;
      case 4:
	result =  book.getAvailable();
	break;
    }
    return result;
  }

  public boolean isLabelProperty(Object arg0, String arg1) {
    return false;
  }
}

After you deploy this demo application into the eWorkbench device, you will see the icon shown in the application list named Test TableViewer Sample. Click Open in the command window to launch it. You will find the table we create.


Figure 2. TableViewer demo application in eWorkbench on a device
TableViewer demo application in eWorkbench on a device


eJFace org.eclipse.jface.preference demo application

PreferencePage

eJFace provides only the PreferencePage to store the required preference data you want, such as server info, user name, and password. Furthermore, it only works while targeting on the eWorkbench. Refer to Resources to see how to develop an eWorkbench application and plug a preference application into it by adding an extension point. In Figure 3, we show how to develop a simple preference application, including the buttons OK, Cancel, and Restore Default.


Listing 9. Add to plugin.xml
                     
<extension point="org.eclipse.ui.preferencePages">
	<page
        	class="preferencesample.PrefPageOne"
        	id="preferenceSample.page1"
                name="Server authentication"/>
</extension>
   

Your preference page class must extend PreferencePage and implement IWorkbenchPreferencePage to let your preference page appear in the eWorkbench. First, we declare the required variable, including String, Text, Label, Button, and PreferenceStore. PreferenceStore stores the name-value pair you typed in. The createContents method is used to display users' preferences.

First, we first create a composite preference page and set the layout with GridLayout. Second, we create a PreferenceStore with a unique name and load data from this PreferenceStore. Third, we create three text fields that allow the user to type in the desired values. The values are server address, username, and password. We use SetDefaultValue() to set the default values for these fields. Users will see these defaults when they open the preferences page.

We use performDefaults to reset the default values. Use performOK to save the value you type in when you click OK. Use performCancel to exit this preference page without saving when you click Cancel. init(IWorkbench arg0) is the required method you must implement when a preference page implements the IWorkbenchPreferencePage.


Listing 10. Preference page sample code
                
public class PrefPageOne extends PreferencePage implements IWorkbenchPreferencePage{
  private static final String SERVERADDR   = "SERVERADDR";
  private static final String USERNAME     = "USERNAME";
  private static final String USERPASSWORD = "USERPASSWORD";
	
  private Text fieldOne;
  private Text fieldTwo;
  private Text fieldThree;
	
  Label label1, label2, label3;
  Composite composite;
  Button defaultbutton;
  PreferenceStore preferenceStore;
	
  protected Control createContents(Composite parent){
    composite = new Composite(parent, SWT.NONE);
    composite.setLayout(new GridLayout(2,false));
    preferenceStore = new PreferenceStore("com.ibm.test.ejface.preference");
    try {
	 preferenceStore.load();
    }catch (IOException e) {}
	    
    label1 = new Label(composite, SWT.LEFT);
    label1.setText("Server address:");
    label1.setground(new Color(composite.getDisplay(),0x66, 0xCC, 0xFF));
    fieldOne = new Text(composite, SWT.SINGLE | SWT.BORDER);
    fieldOne.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		
    label2 = new Label(composite, SWT.LEFT);
    label2.setText("Username:");
    fieldTwo = new Text(composite, SWT.SINGLE | SWT.BORDER);
    fieldTwo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		
    label3 = new Label(composite, SWT.LEFT);
    label3.setText("Password:");
    fieldThree = new Text(composite, SWT.SINGLE | SWT.BORDER | SWT.PASSWORD);
    fieldThree.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		
    SetDefaultValue();
		
    fieldOne.setText(preferenceStore.getString(SERVERADDR));
    fieldTwo.setText(preferenceStore.getString(USERNAME));
    fieldThree.setText(preferenceStore.getString(USERPASSWORD));
		
    defaultbutton = new Button(composite,SWT.PUSH | SWT.LEFT);
    defaultbutton.setText("Restore to Default value");
    defaultbutton.addSelectionListener(new SelectionListener(){
      public void widgetSelected(SelectionEvent e) {
        performDefaults();
      }
      public void widgetDefaultSelected(SelectionEvent e) {
      }});
      
    return composite;
  }
  
  protected void performDefaults(){
    fieldOne  .setText(preferenceStore.getDefaultString(SERVERADDR));
    fieldTwo  .setText(preferenceStore.getDefaultString(USERNAME));
    fieldThree.setText(preferenceStore.getDefaultString(USERPASSWORD));
  }
	
  public boolean performOk(){
    if(fieldOne   != null && fieldOne  .getCharCount() != 0)
       preferenceStore.setValue(SERVERADDR,   fieldOne  .getText());
    if(fieldTwo   != null && fieldTwo  .getCharCount() != 0) 
       preferenceStore.setValue(USERNAME,     fieldTwo  .getText());
    if(fieldThree != null && fieldThree.getCharCount() != 0) 
       preferenceStore.setValue(USERPASSWORD, fieldThree.getText());
    try{
        preferenceStore.save();
    } catch (IOException e) {
	return false;
    }
    return true;
  }
	
  private void SetDefaultValue() {
    if (fieldOne   != null && fieldOne.getCharCount()  == 0) {
        preferenceStore.setDefault(SERVERADDR, "www.ibm.com");
    }
    if (fieldTwo   != null && fieldTwo.getCharCount()  == 0) {
        preferenceStore.setDefault(USERNAME, "Administrator");
    }
    if (fieldThree != null && fieldThree.getCharCount()== 0) {
        preferenceStore.setDefault(USERPASSWORD, "admin");
    }			
  }
	
  public boolean performCancel() {
    composite.dispose();
    this.dispose();
    return true;
  }
  
  public void init(IWorkbench arg0) {
  }
}

After you deploy this demo application into the device in eWorkbench, you will see the icon shown in the Preference Demo Application list. Click OK to save what you enter, click Cancel to exit the preference page, or click Restore to set the value of each text field back to the default.


Figure 3. Preference Page demo application in eWorkbench device
Preference Page demo application in eWorkbench device


eJFace org.eclipse.jface.resource demo application

eJFace provides significant libraries of org.eclipse.jface.resource packages only. In our demo application, we demonstrate how to use ImageRegistry and fontRegistry to manage the image and font objects efficiently. JFaceColors is also introduced to help manage colors of corresponding widgets. In addition, we display how to use the command widget to fulfill org.eclipse.jface.action functionality.

The demonstration code is listed in Listing 11, which sets font, color, and image into corresponding widgets using a registry. We also show how to construct an eSWT command widget. In addition, it only works while targeting applications in eWorkbench. See Resources to learn how to develop an eWorkbench application.

ImageRegistry is used to store and load different images. With the put() and get() methods, you can assign a name to an image and manage many images easily. FontRegistry is similar to ImageRegistry and is used to store and load different fontData. With put and get methods, the user can manage fonts efficiently. JFaceResources can be used to manage ImageRegistry and FontRegistry throughout the entire program.

JFaceColors can assign specific colors to the foreground and background of a widget dynamically. StringConverter provides Java string manipulation capability. In this demo, we use it to cut a string object to StringArray.

The command widget is a useful API of eSWT. Command appears only while the attached widget gets focused. In this sample, RecoverCommand is attached with the composite object. RecoverCommand will show while composite is focused. Otherwise, RecoverCommand disappears. We add SelectionListener to RecoverCommand. While RecoverCommand is selected, the widgetSelected is called.

Here is the resource demo sample on the device (see Downloads for source code).


Listing 11. Resource sample code
                
//ImageRegistry demo
ImageRegistry ir = new ImageRegistry();
ir.put("img1",new Image(display,getClass().getResourceAsStream("/icons/ibm1.png")));
ir.put("img2",new Image(display,getClass().getResourceAsStream("/icons/ibm2.png")));
		
Label Imagelabel = new Label (composite, SWT.LEFT);
Imagelabel.setImage(ir.get("img1"));

//FontRegistry demo
FontRegistry fr = new FontRegistry(composite.getDisplay());
FontData[] fd = new FontData[2];
fd[0]= new FontData("Tacoma",20, SWT.NORMAL);
fd[1]= new FontData("Times New Roman",12, SWT.NORMAL);
fr.put("SysFont", fd);

Label Fontlabel = new Label (composite, SWT.LEFT);
Fontlabel.setText("FontRegistry");
Font normalfont = new Font(composite.getDisplay(),fr.getFontData("SysFont")[0]);
Fontlabel.setFont(normalfont);		
JFaceResources.setFontRegistry(fr);
Font font = new Font(display, JFaceResources.getFontRegistry().getFontData
("SysFont")[1]);

//JFaceColors demo
Label JFaceColorslabel = new Label (composite, SWT.LEFT);
JFaceColorslabel.setText("JFaceColors");
JFaceColors.setColors(JFaceColorslabel, composite.getDisplay().getSystemColor
    (SWT.COLOR_DARK_YELLOW), composite.getDisplay().getSystemColor(SWT.COLOR_BLUE));
	
String[] stringArray = StringConverter.asArray("eJface   Developer    Works");

Command RecoverCommand = new Command(composite, Command.OK, 0);
RecoverCommand.setText("Default Setting");
RecoverCommand.addSelectionListener(new SelectionListener() {
	public void widgetSelected(SelectionEvent e) {
				Imagelabel.setImage(ir.get("image1"));
				Imagelabel.redraw();
				
				Fontlabel.setFont(font);
				Fontlabel.redraw();				
				stringButton.setText("eJface   Developer    Works");
			}
	public void widgetDefaultSelected(SelectionEvent e) {
			}
});


Figure 4. eJFace resource sample (before change)
eJFace resource Sample (before change)


Figure 5. eJFace resource sample (after change)
eJFace resource Sample (after change)


eJFace integration demo application on eWorkbench

Now we integrate all of the subfunctions described above into one sample. First, we create one TreeViewer that can display NBA or MLB players according to your choice. Second, there is one preference page with default values based on whether you are in the NBA page or MLB page. Third, you can highlight one team or player in the window, then click 2005~2006 record in the command window. The device creates a table that records this record, which is made with TableViewer. Since the source code is too big to show here, and there is no new function added in this integration sample, you can find the source code in Downloads for further study. Figures 6, 7, and 8 illustrate the integration on a device.


Figure 6. eJFace integration sample shown in eWorkbench
eJFace integration sample shown in eWorkbench

Figure 7. NBA preference page; default value is NBA-based
NBA preference page; default value is NBA-based

Figure 8. Table displaying the players' records
Table displaying the players' records


Conclusion

This article illustrates the steps needed to develop an eJFace application. We distinguished JFace and eJFace, and has explored the reasons behind eJFace's development. Along the way, we reviewed the structure of the eJFace library, its APIs, and their use, learned how to develop an eJFace, eSWT, and eWorkbench application within an eRCP environment, and added eJFace functionality to an application.



Download

DescriptionNameSizeDownload method
Source codeeJFaceSample_1.0.zip515KB HTTP

Information about download methods


Resources

Learn

Get products and technologies

Discuss

  • The eRCP mailing lists offer near real-time information about eRCP.

  • The eRCP newsgroups has many resources for people interested in eRCP. (Selecting this will launch your default Usenet news reader application and open eclipse.technology.ercp.)

  • The Eclipse Platform newsgroups should be your first stop to discuss questions regarding Eclipse. (Selecting this will launch your default Usenet news reader application and open eclipse.platform.)

  • The Eclipse newsgroups has many resources for people interested in using and extending Eclipse.

  • Participate in developerWorks blogs and get involved in the developerWorks community.

About the authors

Sam Lo

Sam Lo is a software developer at the IBM China Software Development Lab and works in Lotus client technology concurrently. He loves to travel, play musical instruments, and follow sports. He is a Houston Rockets and Detroit Tigers fan, which explains the sports-related examples in this article.

Eric Hsu

Eric Hsu is a software developer at the IBM China Software Development Lab in Taipei. He works in Lotus Expediter client technology and Eclipse eRCP project development. He is a committer to the Eclipse eRCP project, as well.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source, Java technology
ArticleID=254180
ArticleTitle=Developing embedded applications with eJFace
publish-date=09112007
author1-email=locl@tw.ibm.com
author1-email-cc=
author2-email=mfhsu@tw.ibm.com
author2-email-cc=cappel@us.ibm.com

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers