Open main menu

CDOT Wiki β

Changes

Teams Winter 2011/team1/RCP/Create RPC Application

12,001 bytes removed, 15:14, 4 March 2011
Replaced content with '=== 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]]
1
edit