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

From CDOT Wiki
Jump to: navigation, search
(6. Add Highlights to Search)
(6. Add Highlights to Search)
Line 222: Line 222:
  
 
=== 6. Add Highlights to Search ===
 
=== 6. Add Highlights to Search ===
6.1 Create a new helper class and put it in <code>util</code> package:<br/>
+
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>
 
  <pre>
 
   package cs.ecl.rcp.simplercp.util;
 
   package cs.ecl.rcp.simplercp.util;
Line 285: Line 286:
 
  }
 
  }
 
  </pre><br/>
 
  </pre><br/>
5.2
+
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 13:58, 4 March 2011

1. Create project and data model

2. Show Data in Application

2.1 Columns data in a JFace table can be hold in ModelProvider and it is defined via instances of TableViewerColumn object:

viewer.setInput(ModelProvider.INSTANCE.getStudents());

and

TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0], 0);

2.2 Add the following lines to StudentsView.java class:
Private variable:
private TableViewer viewer;
Change the createColumns()method:

   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();
      }
    });
 

Add the same functionality for other three columns 2.3 Run your application:
Create1.png

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 class:

   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();
	}
}

3.3 Assign EditorSupport objects to your TableColumnViewers in your StudentView class.
Add the following line at the end of the LabelProvider is set:

col.setEditingSupport(new IdEditingSupport(viewer));

3.4 Run your application. You should now be able to modify the content of the table:
Create2.png

4. Add Sorting Option

4.1 Create a new Class StudentViewerComparator.java put it in package sorter:

   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;
     }
 }
 

4.2 Add new private variable to StudentsView class:
private StudentViewerComparator comparator;
4.3 Add the following lines to the end of createPartControl() method:

  comparator = new StudentViewerComparator();
  viewer.setComparator(comparator);
 

4.4 Add SelectionListener the to the createTableViewerColumn() method:

column.addSelectionListener(getSelectionAdapter(column, colNumber));

4.5 Add new method:

   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;
  }

4.6 Run the application. Click on a column header, the table should be sorted according to the content of this column.
There will also appear a sort-direction in the top of the column:
Create3.png

5. Add Filter(Search) Option

5.1 Create new class that extends ViewerFilter:

  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;
    }
 }
 

5.2 Create a new private variable in the StudentView class:

 private StudentFilter filter;

5.3 Add the filter to createPartControl() method:

   filter = new StudentFilter();
   viewer.addFilter(filter);
 

5.4 Run the application. Search for the student:
Create4.png

6. Add Highlights to Search

6.1 Create a new helper class and put it in util package.
Method in this class use logic that is case-insensitive, because filter is case-insensitive:

  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;
    }
 }
 

6.2 Change the way columns are created in the createColumns() method.
Following is the code for the first column, other columns need to be changed in similar way:

         // 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));
 

6.3 Run the application. Now your search matches are highlighted:
Create5.png