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

From CDOT Wiki
Jump to: navigation, search
(5. Add Filter(Search) Option)
(Replaced content with '=== 1. Create project and data model ===')
Line 1: Line 1:
 
=== 1. Create project and data model ===
 
=== 1. Create project and data model ===
 
=== 2. Show Data in Application ===
 
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/>
 
<code>viewer.setInput(ModelProvider.INSTANCE.getStudents());</code><br/>
 
and
 
<code>TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0], 0);</code>
 
2.2 Add the following lines to <code>StudentsView.java</code> class:<br/>
 
Private variable: <br/>
 
<code>private TableViewer viewer;</code><br/>
 
Change the <code>createColumns()method:<br/>
 
<pre>
 
  String[] titles = { "Id", "First name", "Last name", "Program" };
 
  int[] bounds = { 100, 100, 100, 100 };
 
  // First column is for the student id
 
  TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0], 0);
 
  col.setLabelProvider(new ColumnLabelProvider() {
 
      @Override
 
      public String getText(Object element) {
 
        Student s = (Student) element;
 
        return s.getId();
 
      }
 
    });
 
</pre><br/>
 
Add the same functionality for other three columns
 
2.3 Run your application:<br/>
 
[[Image: Create1.png | 400px]]<br/>
 
 
=== 3. Add Edit Cell Data Option ===
 
3.1 To make the column editable you need to define an object of type <code>EditingSupport/<code> on your TableColumnViewer.
 
3.2 Create new class for each column that extends <code>EditingSupport</code> class:
 
<pre>
 
  package cs.ecl.rcp.simplercp.edit;
 
 
  import org.eclipse.jface.viewers.CellEditor;
 
  import org.eclipse.jface.viewers.EditingSupport;
 
  import org.eclipse.jface.viewers.TableViewer;
 
  import org.eclipse.jface.viewers.TextCellEditor;
 
 
 
  import cs.ecl.rcp.simplercp.model.Student;
 
 
  public class IdEditingSupport extends EditingSupport {
 
private final TableViewer viewer;
 
 
public IdEditingSupport(TableViewer viewer) {
 
super(viewer);
 
this.viewer = viewer;
 
}
 
 
@Override
 
protected CellEditor getCellEditor(Object element) {
 
return new TextCellEditor(viewer.getTable());
 
}
 
 
@Override
 
protected boolean canEdit(Object element) {
 
return true;
 
}
 
 
@Override
 
protected Object getValue(Object element) {
 
return ((Student) element).getId();
 
}
 
 
@Override
 
protected void setValue(Object element, Object value) {
 
((Student) element).setId(String.valueOf(value));
 
viewer.refresh();
 
}
 
}
 
</pre><br/>
 
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/>
 
<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/>
 
 
=== 4. Add Sorting Option ===
 
4.1 Create a new Class <code>StudentViewerComparator.java</code> put it in package <code>sorter</code>:<br/>
 
<pre>
 
  package cs.ecl.rcp.simplercp.sorter;
 
 
  import org.eclipse.jface.viewers.Viewer;
 
  import org.eclipse.jface.viewers.ViewerComparator;
 
 
  import cs.ecl.rcp.simplercp.model.*;
 
 
  public class StudentViewerComparator extends ViewerComparator {
 
      private int propertyIndex;
 
      private static final int DESCENDING = 1;
 
      private int direction = DESCENDING;
 
 
      public StudentViewerComparator() {
 
        this.propertyIndex = 0;
 
        direction = DESCENDING;
 
      }
 
 
      public void setColumn(int column) {
 
        if (column == this.propertyIndex) {
 
            // Same column as last sort; toggle the direction
 
            direction = 1 - direction;
 
        } else {
 
            // New column; do an ascending sort
 
            this.propertyIndex = column;
 
            direction = DESCENDING;
 
        }
 
      }
 
 
      @Override
 
      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 ===
 
5.1 Create new class that extends <code>ViewerFilter</code>. This class uses case-insensitive filtering:<br/>
 
<pre>
 
  package cs.ecl.rcp.simplercp.filter;
 
 
import org.eclipse.jface.viewers.Viewer;
 
import org.eclipse.jface.viewers.ViewerFilter;
 
 
import cs.ecl.rcp.simplercp.model.*;
 
 
public class StudentFilter extends ViewerFilter {
 
    private String searchString;
 
 
    public void setSearchText(String s) {
 
        // Search must be a substring of the existing value
 
        this.searchString = ".*" + s + ".*";
 
    }
 
 
    @Override
 
    public boolean select(Viewer viewer, Object parentElement, Object element) {     
 
        if (searchString == null || searchString.length() == 0) {
 
            return true;
 
        }
 
        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 false;
 
    }
 
}
 
</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/>
 
Method in this class use logic that is case-insensitive, because filter is case-insensitive:<br/>
 
<pre>
 
  package cs.ecl.rcp.simplercp.util;
 
 
  import java.util.ArrayList;
 
  import java.util.List;
 
 
  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/>
 
6.2 Change the way columns are created in the <code>createColumns()</code> method.<br/>
 
Following is the code for the first column, other columns need to be changed in similar way:<br/>
 
<pre>
 
        // First column is for the id
 
        TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0], 0);
 
        col.setLabelProvider(new StyledCellLabelProvider() {
 
            @Override
 
            public void update(ViewerCell cell) {
 
                String search = searchText.getText();
 
                Student student = (Student) cell.getElement();
 
                String cellText = student.getId();
 
                cell.setText(cellText);
 
                if (search != null && search.length() > 0) {
 
                    int intRangesCorrectSize[] = SearchUtil
 
                            .getSearchTermOccurrences(search, cellText);
 
                    List<StyleRange> styleRange = new ArrayList<StyleRange>();
 
                    for (int i = 0; i < intRangesCorrectSize.length / 2; i++) {
 
                        int start = intRangesCorrectSize[i];
 
                        int length = intRangesCorrectSize[++i];
 
                        StyleRange myStyledRange = new StyleRange(start,
 
                                length, null, colorYellow);
 
 
                        styleRange.add(myStyledRange);
 
                    }
 
                    cell.setStyleRanges(styleRange
 
                            .toArray(new StyleRange[styleRange.size()]));
 
                } else {
 
                    cell.setStyleRanges(null);
 
                }
 
 
                super.update(cell);
 
                setStatusLine("Student search has been updated");
 
            }         
 
        });
 
        col.setEditingSupport(new IdEditingSupport(viewer));
 
</pre><br/>
 
6.3 Run the application. Now your search matches are highlighted:<br/>
 
[[Image: Create5.png | 400px]]
 

Revision as of 15:14, 4 March 2011

1. Create project and data model