Difference between revisions of "Teams Winter 2011/team1/RCP/Create RPC Application"

From CDOT Wiki
Jump to: navigation, search
(6. Add Highlights to Search)
(Create a RCP Application)
 
(61 intermediate revisions by 2 users not shown)
Line 1: Line 1:
=== 1. Create project and data model ===
+
=== Create a RCP Application ===
 +
'''This tutorial uses the [http://www.vogella.de/articles/EclipseJFaceTable/article.html#jfaceviewers  Jface Tutorial] as reference.''' <br/>
 +
In this tutorial we are going to demonstrate how to build a simple RCP application to maintain student's information. We keep the data in a List object and will not preserve data. <br/>
  
=== 2. Show Data in Application ===
+
To begin with, we create a simple RCP from the "Hello World" RCP template. The will add our Model classes. Eventually we use perspective, view, Jface viewe and Commands, to display, edit, Add and Delete students' records.<br/>
2.1 Columns data in a JFace table can be hold in <code>ModelProvider</code> and it is defined via instances of <code>TableViewerColumn</code> object:<br/>
+
==== Start The Application ====
<code>viewer.setInput(ModelProvider.INSTANCE.getStudents());</code><br/>
+
Create a new plug-in project from File menu (File>New>Project>Plug-in Development> Plug-in project).<br/>
and
+
[[Image: createRCPApp1.jpg | 400px]]<br/>
<code>TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0], 0);</code>
+
<br/>
2.2 Add the following lines to <code>StudentsView.java</code> class:<br/>
+
Name it: "cs.ecl.rcp.SimpleRCP"<br/>
Private variable: <br/>
+
[[Image: createRCPApp2.jpg | 400px]]<br/>
<code>private TableViewer viewer;</code><br/>
+
<br/>
Change the <code>createColumns()method:<br/>
+
Select "Yes" in responce to the question:" Would you like to create a rich client application?"<br/>
<pre>
+
[[Image: createRCPApp3.jpg | 400px]]<br/>
  String[] titles = { "Id", "First name", "Last name", "Program" };
+
<br/>
  int[] bounds = { 100, 100, 100, 100 };
+
Select the "Hello RCP" in the Templates screen.<br/>
  // First column is for the student id
+
[[Image: createRCPApp4.jpg | 400px]]<br/>
  TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0], 0);
+
<br/>
  col.setLabelProvider(new ColumnLabelProvider() {
+
Un-check "Add branding".<br/>
      @Override
+
[[Image: createRCPApp5.jpg | 400px]]<br/>
      public String getText(Object element) {
+
<br/>
        Student s = (Student) element;
+
The "RCP" project is created with some classes already in it. We will modify this project to create our RCP application for the purpose if this tutorial.<br/>
        return s.getId();
+
[[Image: createRCPApp6.jpg | 700px]]<br/>
      }
+
<br/>
    });
+
In the "ApplicationWorkbenchWindowAdvisor" class, modify the preWindoOpen() method to set the title of the window ar "Simple RCP Application".<br/>
</pre><br/>
+
<code>ApplicationWorkbenchWindowAdvisor.java </code> to <code> true</code>
Add the same functionality for other three columns
+
<source lang=java>
2.3 Run your application:<br/>
 
[[Image: Create1.png | 400px]]<br/>
 
  
=== 3. Add Edit Cell Data Option ===
+
public void preWindowOpen() {
3.1 To make the column editable you need to define an object of type <code>EditingSupport/<code> on your TableColumnViewer.
+
        IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
3.2 Create new class for each column that extends <code>EditingSupport</code> class:
+
        configurer.setInitialSize(new Point(400, 300));
<pre>
+
        configurer.setShowCoolBar(false);
  package cs.ecl.rcp.simplercp.edit;
+
        configurer.setShowStatusLine(false);
 +
        configurer.setTitle("Simple RCP Application"); //$NON-NLS-1$
 +
        configurer.setShowStatusLine(true);
 +
        configurer.setShowPerspectiveBar(true);
 +
    }
 +
</source>
  
  import org.eclipse.jface.viewers.CellEditor;
+
==== Run The Application ====
  import org.eclipse.jface.viewers.EditingSupport;
+
To run the application, right click on the project and select :Run As> Eclipse Application. Alternatively, you can click on the "Run an Eclipse Application" In the "Testing section of the project Overview window.<br/>
  import org.eclipse.jface.viewers.TableViewer;
+
[[Image: RCPRun1.jpg | 700px]]<br/>
  import org.eclipse.jface.viewers.TextCellEditor;
+
<br/>
 
+
At this point, the application starts and looks like this:<br/>
  import cs.ecl.rcp.simplercp.model.Student;
+
[[Image: RCPRun2.jpg | 350px]]<br/>
 +
<br/>
 +
'''Run Configuration'''<br/>
 +
You can also set the run configuration if required, for example if there is a separate project for a view and you want to add that view to the perspective of the current project you need to make sure that both projects are running, so you need to set that in the run configuration, and you can reach it by right clicking on the project in Project explorer view and select Run As> Run configuration, and double clicking on the '''Eclipse Application''' to create a new Run configuration for the application. However, for this project we do not need any new run configuration. <br/>
  
  public class IdEditingSupport extends EditingSupport {
+
=== Add Model ===
private final TableViewer viewer;
+
In order to have a data model for Student, we need to create a "Student Class" which keeps an student's data and "ModelProvider" Class that creates and keeps a list of Student class objects.<br/>
 +
==== Create Model Package ====
 +
Create a package named "cs.ecl.rcp.simplercp.model" in the src directory of your project.<br/>
 +
==== Add Model Class(s) ====
 +
Add a class named "Student" in the above package.
 +
Add the student related fields and make sure that the class uses "PropertyChangeSupport" and "PropertyChangeListener" when setting the properties. For this purpose we need to have an instance of the "PropertyChangeSupport" class to be build by passing the Student object(this) to it, and implement the metods:"addPropertyChangeListener" and "removePropertyChangeListener". The following code demonstrates how to create the Student Model and how to add Property Change Support to the class.
  
public IdEditingSupport(TableViewer viewer) {
+
<code>Student.java </code>
super(viewer);
 
this.viewer = viewer;
 
}
 
  
@Override
+
<source lang=java>
protected CellEditor getCellEditor(Object element) {
 
return new TextCellEditor(viewer.getTable());
 
}
 
  
@Override
+
package cs.ecl.rcp.simplercp.model;
protected boolean canEdit(Object element) {
 
return true;
 
}
 
  
@Override
+
import java.beans.PropertyChangeListener;
protected Object getValue(Object element) {
+
import java.beans.PropertyChangeSupport;
return ((Student) element).getId();
 
}
 
  
@Override
+
public class Student {
protected void setValue(Object element, Object value) {
+
    private String id;
((Student) element).setId(String.valueOf(value));
+
    private String firstName;
viewer.refresh();
+
    private String lastName;
}
+
    private String program; 
}
+
 
</pre><br/>
+
    private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
3.3 Assign <code>EditorSupport</code> objects to your <code>TableColumnViewers </code>in your <code>StudentView</code> class.<br/>
+
 
Add the following line at the end of the <code>LabelProvider</code> is set:<br/>
+
    public Student(){
<code>col.setEditingSupport(new IdEditingSupport(viewer));</code><br/>
+
    }
3.4 Run your application. You should now be able to modify the content of the table:<br/>
+
 
[[Image: Create2.png | 400px]]<br/>
+
    public Student(String id, String firstName, String lastName, String program){
 +
        super();
 +
        this.id= id;
 +
        this.firstName= firstName;
 +
        this.lastName= lastName;
 +
        this.program= program;
 +
    }
 +
 
 +
 
 +
    public void addPropertyChangeListener(String propertyName,PropertyChangeListener listener) {
 +
        propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
 +
    }
 +
 
 +
    public void removePropertyChangeListener(PropertyChangeListener listener) {
 +
        propertyChangeSupport.removePropertyChangeListener(listener);
 +
    }
  
=== 4. Add Sorting Option ===
+
    public String getId() {
4.1 Create a new Class <code>StudentViewerComparator.java</code> put it in package <code>sorter</code>:<br/>
+
        return id;
<pre>
+
    }
  package cs.ecl.rcp.simplercp.sorter;
 
  
  import org.eclipse.jface.viewers.Viewer;
+
    public String getFirstName() {
  import org.eclipse.jface.viewers.ViewerComparator;
+
        return firstName;
 +
    }
  
  import cs.ecl.rcp.simplercp.model.*;
+
    public String getLastName() {
 +
        return lastName;
 +
    }
  
  public class StudentViewerComparator extends ViewerComparator {
+
    public String getProgram() {
      private int propertyIndex;
+
        return program;
      private static final int DESCENDING = 1;
+
    }
      private int direction = DESCENDING;
 
  
      public StudentViewerComparator() {
+
 
         this.propertyIndex = 0;
+
 
         direction = DESCENDING;
+
    public void setId(String id) {
      }
+
         propertyChangeSupport.firePropertyChange("id", this.id,
 
+
                this.id = id);
      public void setColumn(int column) {
+
    }
         if (column == this.propertyIndex) {
+
 
            // Same column as last sort; toggle the direction
+
    public void setFirstName(String firstName) {
            direction = 1 - direction;
+
         propertyChangeSupport.firePropertyChange("firstName", this.firstName,
        } else {
+
                this.firstName = firstName);
            // New column; do an ascending sort
+
    }
            this.propertyIndex = column;
+
 
            direction = DESCENDING;
+
    public void setLastName(String lastName) {
        }
+
         propertyChangeSupport.firePropertyChange("lastName", this.lastName,
      }
+
                this.lastName = lastName);
 +
    }
 +
 
 +
    public void setProgram(String program) {
 +
        propertyChangeSupport.firePropertyChange("program", this.program,
 +
                this.program = program);
 +
    }
 +
    public String toString() {
 +
        return id +" "+firstName + " " + lastName + " "+ program ;
 +
    }
 +
}
 +
 
 +
 
  
      @Override
+
</source>
      public int compare(Viewer viewer, Object e1, Object e2) {
 
        Student s1 = (Student) e1;
 
        Student s2 = (Student) e2;
 
        int rc = 0;
 
        switch (propertyIndex) {
 
        case 0:
 
            rc = s1.getId().compareTo(s2.getId());
 
            break;           
 
        case 1:
 
            rc = s1.getFirstName().compareTo(s2.getFirstName());
 
            break;
 
        case 2:
 
            rc = s1.getLastName().compareTo(s2.getLastName());
 
            break;
 
        case 3:
 
            rc = s1.getProgram().compareTo(s2.getProgram());
 
            break;       
 
        default:
 
            rc = 0;
 
        }
 
        // If descending order, flip the direction
 
        if (direction == DESCENDING) {
 
            rc = -rc;
 
        }
 
        return rc;
 
    }
 
}
 
</pre><br/>
 
4.2 Add new private variable to <code>StudentsView</code> class:<br/>
 
<code>private StudentViewerComparator comparator;</code><br/>
 
4.3 Add the following lines to the end of <code>createPartControl()</code> method:<br/>
 
<pre>
 
  comparator = new StudentViewerComparator();
 
  viewer.setComparator(comparator);
 
</pre><br/>
 
4.4 Add <code>SelectionListener</code> the to the <code>createTableViewerColumn()</code> method:
 
<code>column.addSelectionListener(getSelectionAdapter(column, colNumber));</code><br/>
 
4.5 Add new method:<br/>
 
<pre>
 
  private SelectionAdapter getSelectionAdapter(final TableColumn column, final int index) {     
 
    SelectionAdapter selectionAdapter = new SelectionAdapter() {
 
        @Override
 
        public void widgetSelected(SelectionEvent e) {
 
            comparator.setColumn(index);
 
            int dir = viewer.getTable().getSortDirection();
 
            if (viewer.getTable().getSortColumn() == column) {
 
              dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
 
            } else {
 
              dir = SWT.DOWN;
 
            }
 
            viewer.getTable().setSortDirection(dir);
 
            viewer.getTable().setSortColumn(column);
 
            viewer.refresh();
 
        }
 
        };
 
    return selectionAdapter;
 
  }
 
</pre><br/>
 
4.6 Run the application. Click on a column header, the table should be sorted according to the content of this column.<br/>
 
There will also appear a sort-direction in the top of the column:<br/>
 
[[Image: Create3.png | 400px]]<br/>
 
  
=== 5. Add Filter(Search) Option ===
+
==== Add Model Provider ====
5.1 Create new class that extends <code>ViewerFilter</code>:<br/>
+
"ModelProvider" class creates and maintains an ArrayList of Student objects and helps us find an student by it's id from the list of students.<br/>
<pre>
+
<code>ModelProvider.java </code>
  package cs.ecl.rcp.simplercp.filter;
 
  
import org.eclipse.jface.viewers.Viewer;
+
<source lang=java>
import org.eclipse.jface.viewers.ViewerFilter;
+
package cs.ecl.rcp.simplercp.model;
  
import cs.ecl.rcp.simplercp.model.*;
+
import java.util.ArrayList;
 +
import java.util.List;
  
public class StudentFilter extends ViewerFilter {
+
public enum ModelProvider {
     private String searchString;
+
     INSTANCE;
  
     public void setSearchText(String s) {
+
     private List<Student> students;
         // Search must be a substring of the existing value
+
 
         this.searchString = ".*" + s + ".*";
+
    private ModelProvider() {
 +
        students = new ArrayList<Student>();
 +
         // Data could be retrieved here from database
 +
        students.add(new Student("01234567","Ladan", "Zahiroleslam", "CPA"));
 +
         students.add(new Student("09876543", "Anastasia", "Semionova", "CPA"));
 +
        students.add(new Student("01122334", "Minoo", "Ziaei", "CPA"));
 +
        students.add(new Student("02233445", "Sergiu", "Ecob", "CPA"));
 
     }
 
     }
  
    @Override
+
     public Student getPersonById(String id) {
     public boolean select(Viewer viewer, Object parentElement, Object element) {     
+
         for (Student student : students) {
        if (searchString == null || searchString.length() == 0) {
+
             if (student.getId() == id) {
            return true;
+
                return student;
         }
+
             }
        Student s = (Student) element;
 
        if (s.getFirstName().toLowerCase().matches(searchString.toLowerCase())) {
 
             return true;
 
        }
 
        if (s.getLastName().toLowerCase().matches(searchString.toLowerCase())) {
 
            return true;
 
        }
 
        if (s.getProgram().toLowerCase().matches(searchString.toLowerCase())) {
 
             return true;
 
        }
 
        if (s.getId().matches(searchString)) {
 
            return true;
 
 
         }
 
         }
 +
        return null;
 +
    }
  
         return false;
+
    public List<Student> getStudents() {
 +
         return students;
 
     }
 
     }
}
 
</pre><br/>
 
5.2 Create a new private variable in the <code>StudentView</code> class:
 
  <code>private StudentFilter filter;</code><br/>
 
5.3 Add the filter to <code>createPartControl()</code> method:<br/>
 
<pre>
 
  filter = new StudentFilter();
 
  viewer.addFilter(filter);
 
</pre><br/>
 
5.4 Run the application. Search for the student:<br/>
 
[[Image: Create4.png | 400px]]<br/>
 
  
=== 6. Add Highlights to Search ===
+
}
6.1 Create a new helper class and put it in <code>util</code> package:<br/>
 
<pre>
 
  package cs.ecl.rcp.simplercp.util;
 
  
  import java.util.ArrayList;
+
</source>
  import java.util.List;
+
<br/>
 
+
[[Teams_Winter_2011/team1| Index Page]]  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [[Teams_Winter_2011/team1/RCP/Define_and_use_commands| Next>>]]
  public class SearchUtil {
 
    public static int[] getSearchTermOccurrences(final String searchTerm,
 
            final String content) {
 
        if (searchTerm == null || searchTerm.length() == 0) {
 
            return new int[0];
 
        }
 
        if (content == null) {
 
            throw new IllegalArgumentException("content is null");
 
        }
 
        final List<Integer> list = new ArrayList<Integer>();
 
        int searchTermLength = searchTerm.length();
 
        int index;
 
        int fromIndex = 0;
 
        int lastIndex = -1;
 
        int lastLength = 0;
 
        while (true) {
 
            index = content.toLowerCase().indexOf(searchTerm.toLowerCase(), fromIndex);
 
            if (index == -1) {
 
                // no occurrence of "searchTerm" in "content" starting from
 
                // index "fromIndex"
 
                if (lastIndex != -1) {
 
                    // but there was a previous occurrence
 
                    list.add(Integer.valueOf(lastIndex));
 
                    list.add(Integer.valueOf(lastLength));
 
                }
 
                break;
 
            }
 
            if (lastIndex == -1) {
 
                // the first occurrence of "searchTerm" in "content"
 
                lastIndex = index;
 
                lastLength = searchTermLength;
 
            } else {
 
                if (lastIndex + lastLength == index) {
 
                    // the current occurrence is right after the previous
 
                    // occurrence
 
                    lastLength += searchTermLength;
 
                } else {
 
                    // there is at least one character between the current
 
                    // occurrence and the previous one
 
                    list.add(Integer.valueOf(lastIndex));
 
                    list.add(Integer.valueOf(lastLength));
 
                    lastIndex = index;
 
                    lastLength = searchTermLength;
 
                }
 
            }
 
            fromIndex = index + searchTermLength;
 
        }
 
        final int n = list.size();
 
        final int[] result = new int[n];
 
        for (int i = 0; i != n; i++) {
 
            result[i] = list.get(i);
 
        }
 
        return result;
 
    }
 
}
 
</pre><br/>
 
5.2
 

Latest revision as of 13:55, 9 March 2011

Create a RCP Application

This tutorial uses the Jface Tutorial as reference.
In this tutorial we are going to demonstrate how to build a simple RCP application to maintain student's information. We keep the data in a List object and will not preserve data.

To begin with, we create a simple RCP from the "Hello World" RCP template. The will add our Model classes. Eventually we use perspective, view, Jface viewe and Commands, to display, edit, Add and Delete students' records.

Start The Application

Create a new plug-in project from File menu (File>New>Project>Plug-in Development> Plug-in project).
CreateRCPApp1.jpg

Name it: "cs.ecl.rcp.SimpleRCP"
CreateRCPApp2.jpg

Select "Yes" in responce to the question:" Would you like to create a rich client application?"
CreateRCPApp3.jpg

Select the "Hello RCP" in the Templates screen.
CreateRCPApp4.jpg

Un-check "Add branding".
CreateRCPApp5.jpg

The "RCP" project is created with some classes already in it. We will modify this project to create our RCP application for the purpose if this tutorial.
CreateRCPApp6.jpg

In the "ApplicationWorkbenchWindowAdvisor" class, modify the preWindoOpen() method to set the title of the window ar "Simple RCP Application".
ApplicationWorkbenchWindowAdvisor.java to true

public void preWindowOpen() {
        IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
        configurer.setInitialSize(new Point(400, 300));
        configurer.setShowCoolBar(false);
        configurer.setShowStatusLine(false);
        configurer.setTitle("Simple RCP Application"); //$NON-NLS-1$
        configurer.setShowStatusLine(true);
        configurer.setShowPerspectiveBar(true);
    }

Run The Application

To run the application, right click on the project and select :Run As> Eclipse Application. Alternatively, you can click on the "Run an Eclipse Application" In the "Testing section of the project Overview window.
RCPRun1.jpg

At this point, the application starts and looks like this:
RCPRun2.jpg

Run Configuration
You can also set the run configuration if required, for example if there is a separate project for a view and you want to add that view to the perspective of the current project you need to make sure that both projects are running, so you need to set that in the run configuration, and you can reach it by right clicking on the project in Project explorer view and select Run As> Run configuration, and double clicking on the Eclipse Application to create a new Run configuration for the application. However, for this project we do not need any new run configuration.

Add Model

In order to have a data model for Student, we need to create a "Student Class" which keeps an student's data and "ModelProvider" Class that creates and keeps a list of Student class objects.

Create Model Package

Create a package named "cs.ecl.rcp.simplercp.model" in the src directory of your project.

Add Model Class(s)

Add a class named "Student" in the above package. Add the student related fields and make sure that the class uses "PropertyChangeSupport" and "PropertyChangeListener" when setting the properties. For this purpose we need to have an instance of the "PropertyChangeSupport" class to be build by passing the Student object(this) to it, and implement the metods:"addPropertyChangeListener" and "removePropertyChangeListener". The following code demonstrates how to create the Student Model and how to add Property Change Support to the class.

Student.java

package cs.ecl.rcp.simplercp.model;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

public class Student {
    private String id;
    private String firstName;
    private String lastName;
    private String program;   
   
    private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
   
    public Student(){
    }
   
    public Student(String id, String firstName, String lastName, String program){
        super();
        this.id= id;
        this.firstName= firstName;
        this.lastName= lastName;
        this.program= program;
    }
   
   
    public void addPropertyChangeListener(String propertyName,PropertyChangeListener listener) {
        propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
    }
   
    public void removePropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.removePropertyChangeListener(listener);
    }

    public String getId() {
        return id;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getProgram() {
        return program;
    }

   
   
    public void setId(String id) {
        propertyChangeSupport.firePropertyChange("id", this.id,
                this.id = id);
    }
   
    public void setFirstName(String firstName) {
        propertyChangeSupport.firePropertyChange("firstName", this.firstName,
                this.firstName = firstName);
    }
   
    public void setLastName(String lastName) {
        propertyChangeSupport.firePropertyChange("lastName", this.lastName,
                this.lastName = lastName);
    }
   
    public void setProgram(String program) {
        propertyChangeSupport.firePropertyChange("program", this.program,
                this.program = program);
    }
    public String toString() {
        return id +" "+firstName + " " + lastName + " "+ program ;
    }
}

Add Model Provider

"ModelProvider" class creates and maintains an ArrayList of Student objects and helps us find an student by it's id from the list of students.
ModelProvider.java

package cs.ecl.rcp.simplercp.model;

import java.util.ArrayList;
import java.util.List;

public enum ModelProvider {
    INSTANCE;

    private List<Student> students;
   
    private ModelProvider() {
        students = new ArrayList<Student>();
        // Data could be retrieved here from database
        students.add(new Student("01234567","Ladan", "Zahiroleslam", "CPA"));
        students.add(new Student("09876543", "Anastasia", "Semionova", "CPA"));
        students.add(new Student("01122334", "Minoo", "Ziaei", "CPA"));
        students.add(new Student("02233445", "Sergiu", "Ecob", "CPA"));
    }

    public Student getPersonById(String id) {
        for (Student student : students) {
            if (student.getId() == id) {
                return student;
            }
        }
        return null;
    }

    public List<Student> getStudents() {
        return students;
    }

}


Index Page            Next>>