Open main menu

CDOT Wiki β

Changes

Teams Winter 2011/team1/RCP/Define and use JFace

12,001 bytes added, 15:12, 4 March 2011
no edit summary
=== 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 columns2.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]] === 6. Adding status line ===16.1 Open <code>ApplicationWorkbenchWindowAdvisor.java</code> file in your project and add the following line at the end of <code>preWindowOpen()</code> method:<br/>
<code>configurer.setShowStatusLine(true); </code>
16.2 Add a new method to this class to set text in status line from different parts of application:<br/>
<pre>
@Override
}
</pre>
16.3 Run the application you should see the following:<br/>
[[Image: StatusLine.png | 400px]]<br/>
16.4 Change the status line from <code>StudentsView.java</code>. Add the following method to this class:<br/>
<pre>
private void setStatusLine(String message) {
Use this method to change text in status line. In the <code>createColumn()</code> method insert the following line at the end of column's <code>update()</code> method:</br>
<code>setStatusLine("Student search has been updated");</code>
16.5 Run the application and try to use Search to find a student. You should get the following:<br/>
[[Image: StatusLine2.png | 400px]]<br/>
16.6 To access status line from the editor use the following line:
<code>IEditorPart.getEditorSite().getActionBars();</code>
=== 27. Adding a perspective ===27.1 Add necessary extensions to the <code>plugin.xml</code>:<br/>
[[Image: PluginXml.png | 400px]]<br/>
27.2 Specify the id ''cs.ecl.simpleRCP.perspective'', name ''RCP Perspective'' and class ''cs.ecl.rcp.simplercp.Perspective'':<br/>
[[Image: PluginXml2.png | 800px]]<br/>
27.3 Click on the <code>class*</code> link to create a class. The method <code>createInitialLayout()</code> in this class is responsible for creating the new perspective.<br/>27.4 The perspective is defined but not yet reachable via the application. To activate the switch between perspectives add the following line to the<br/> <code>ApplicationWorkbenchWindowAdvisor.java</code> in method preWindowOpen():<br/>
<code>configurer.setShowPerspectiveBar(true);</code><br/>
27.5 Run the application. You should be able to select your perspective interactively:<br/>
[[Image: Perspective1.png | 400px]]
1
edit