在我的TableViewer
中有一些TableViewerColumns
。我有一个文本小部件和一个"搜索"按钮。每当我点击搜索时,我都想给表格单元格的文本上色包含(匹配)文本小部件中的单词。我可以通过设置StyledCellLabelProvider
来做到这一点对于每个TableViewerColumn
并重写更新方法,则每个单元格文本的setStyleRanges
都包含该单词。
我试图为每个TableViewerColumn
设置一个ColumnLabelProvider
,因为我需要覆盖getText
方法但在这种情况下,覆盖更新方法似乎对CCD_ 9不起作用。
最后,我不能让StyledCellLabelProvider
和ViewerSorter
一起工作,因为StyledCellLabelProvider
不能具有getText方法。
有没有一种方法可以突出单词,同时具有表格排序功能?
使用从ViewerSorter
(或推荐的ViewerComparator
)派生的自己的类并覆盖
public int compare(Viewer viewer, Object e1, Object e2);
方法,以便您可以从模型对象中获取文本。
类似于:
@Override
public int compare(Viewer viewer, Object e1, Object e2) {
int cat1 = category(e1);
int cat2 = category(e2);
if (cat1 != cat2) {
return cat1 - cat2;
}
String name1 = ... get text from e1
String name2 = ... get text from e2
return getComparator().compare(name1, name2);
}
如果不使用类别,则可以省略代码的第一部分。
我通过在TableLabelProvider
之后设置StyledLabelProvider
并刷新TableViewer
,实现了上述功能。所有这些都是因为ColumnLabelProvider
更新方法不适用于cell.setStyleRanges
!
package mydbtable.gui;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.StatusLineManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wb.swt.SWTResourceManager;
import com.ibm.icu.text.Collator;
public class TableWithSortAndSearch extends ApplicationWindow {
private Object[] tableData;
private Text text_Search;
private Table table;
private TableViewer tableViewer;
private Button btnSearch;
private List<TableViewerColumn> tableViewerColumnList;
/**
* Create the application window.
*/
public TableWithSortAndSearch() {
super(null);
createActions();
addToolBar(SWT.FLAT | SWT.WRAP);
addMenuBar();
addStatusLine();
}
/**
* Create contents of the application window.
* @param parent
*/
@Override
protected Control createContents(Composite parent) {
tableData = (new TableData()).get(5, 4);
tableViewerColumnList = new ArrayList<>();
Composite container = new Composite(parent, SWT.NONE);
container.setLayout(new GridLayout(1, false));
Composite composite = new Composite(container, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
composite.setBounds(0, 0, 10, 10);
composite.setLayout(new GridLayout(2, false));
{
text_Search = new Text(composite, SWT.BORDER);
text_Search.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1));
text_Search.setSize(78, 23);
}
{
btnSearch = new Button(composite, SWT.NONE);
btnSearch.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
btnSearch.setSize(54, 27);
btnSearch.setText("Search");
}
Composite composite_Table = new Composite(container, SWT.NONE);
composite_Table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
composite_Table.setBounds(0, 0, 64, 64);
composite_Table.setLayout(new GridLayout(1, false));
{
tableViewer = new TableViewer(composite_Table, SWT.BORDER | SWT.FULL_SELECTION);
table = tableViewer.getTable();
table.setLinesVisible(true);
table.setHeaderVisible(true);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
table.setSize(339, 84);
TableViewerColumn tableViewerColumn;
int[] columnIdices = { 0 ,1 ,2 ,3 };
for ( final int columnIndex : columnIdices ) {
//column = i;
tableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
TableColumn tableColumn = tableViewerColumn.getColumn();
tableColumn.setMoveable(true);
tableColumn.setWidth(150);
tableColumn.setText("Data" + columnIndex);
//tableViewerColumn.setLabelProvider(new MyColumnLabelProvider(columnIndex));
tableColumn.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
((MyViewerSorter) tableViewer.getSorter()).doSort( columnIndex );
tableViewer.refresh();
for ( int i=0 ; i<tableViewerColumnList.size() ; i++) {
tableViewerColumnList.get(i).setLabelProvider(new MyStyledCellLabelProvider(i));
}
tableViewer.refresh();
}
});
tableViewerColumnList.add(tableViewerColumn);
}
tableViewer.setContentProvider(new StracturedContentProvider());
tableViewer.setLabelProvider(new TableLabelProvider());
tableViewer.setSorter(new MyViewerSorter());
tableViewer.setInput(tableData);
btnSearch.addSelectionListener(createAdapterFor(tableViewer));
}
return container;
}
/**
* Create the actions.
*/
private void createActions() {
// Create the actions
}
/**
* Create the menu manager.
* @return the menu manager
*/
@Override
protected MenuManager createMenuManager() {
MenuManager menuManager = new MenuManager("menu");
return menuManager;
}
/**
* Create the toolbar manager.
* @return the toolbar manager
*/
@Override
protected ToolBarManager createToolBarManager(int style) {
ToolBarManager toolBarManager = new ToolBarManager(style);
return toolBarManager;
}
/**
* Create the status line manager.
* @return the status line manager
*/
@Override
protected StatusLineManager createStatusLineManager() {
StatusLineManager statusLineManager = new StatusLineManager();
return statusLineManager;
}
/**
* Launch the application.
* @param args
*/
public static void main(String args[]) {
try {
TableWithSortAndSearch window = new TableWithSortAndSearch();
window.setBlockOnOpen(true);
window.open();
Display.getCurrent().dispose();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Configure the shell.
* @param newShell
*/
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setText("New Application");
}
/**
* Return the initial size of the window.
*/
@Override
protected Point getInitialSize() {
return new Point(600, 400);
}
private static class StracturedContentProvider implements IStructuredContentProvider {
@Override
public void dispose() {
// TODO Auto-generated method stub
}
@Override
public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
// TODO Auto-generated method stub
}
/**
* Gets the elements for the table
*
* @param arg0
* the model
* @return Object[]
*/
@Override
public Object[] getElements(Object arg0) {
return (Object[]) ((Object[])arg0);
}
}
private class TableLabelProvider implements ITableLabelProvider {
@Override
public void addListener(ILabelProviderListener arg0) {
// TODO Auto-generated method stub
}
@Override
public void dispose() {
// TODO Auto-generated method stub
}
@Override
public boolean isLabelProperty(Object arg0, String arg1) {
// TODO Auto-generated method stub
return false;
}
@Override
public void removeListener(ILabelProviderListener arg0) {
// TODO Auto-generated method stub
}
@Override
public Image getColumnImage(Object arg0, int arg1) {
// TODO Auto-generated method stub
return null;
}
/**
* Gets the text for the specified column
*
* @param arg0
* the row (the data (Object[]) from Object[] tableData)
* @param arg1
* the column (int index)
* @return String
*/
@Override
public String getColumnText(Object arg0, int arg1) {
return (((Object[]) arg0)[arg1])==null ? "" : (((Object[]) arg0)[arg1]).toString();
}
}
private class MyViewerSorter extends ViewerSorter {
private static final int ASCENDING = 0;
private static final int DESCENDING = 1;
private int column;
private int direction;
/**
* Does the sort. If it's a different column from the previous sort, do
* an ascending sort. If it's the same column as the last sort, toggle
* the sort direction.
*
* @param column
*/
public void doSort(int column) {
tableViewer.setLabelProvider(new TableLabelProvider());
if (column == this.column) {
// Same column as last sort, toggle the sorting direction
direction = 1 - direction;
} else {
// Other column than last sort, do a descending sort
for (TableColumn tc : table.getColumns()) {
tc.setImage(null);
}
this.column = column;
direction = DESCENDING;
}
switch (direction) {
case ASCENDING:
table.getColumn(column).setImage(SWTResourceManager.getImage(MyTableViewer.class, "/images/sort_ascending.png"));
break;
case DESCENDING:
table.getColumn(column).setImage(SWTResourceManager.getImage(MyTableViewer.class, "/images/sort_descending.png"));
break;
}
}
/**
* Compares the object for sorting
*/
public int compare(Viewer viewer, Object e1, Object e2) {
int compareResult = 0;
compareResult = Collator.getInstance().compare(((Object[]) e1)[column], ((Object[]) e2)[column]);
// If descending order, flip the direction
if (direction == DESCENDING)
compareResult = -compareResult;
return compareResult;
}
}
// update method doesn't work for cell.setStyleRanges
private class MyColumnLabelProvider extends ColumnLabelProvider {
private final int columnIndex;
MyColumnLabelProvider(int columnIndex) {
this.columnIndex = columnIndex;
}
@Override
public String getText(Object element) {
return super.getText( ((Object[])element)[columnIndex].toString() );
//return ((Object[])element)[columnIndex].toString();
}
@Override
public void update(ViewerCell cell) {
if ( cell.getText().toLowerCase().contains(text_Search.getText().toLowerCase()) ) {
System.out.println("yes -> " + cell.getText().toLowerCase().indexOf(text_Search.getText().toLowerCase()) + ", " + text_Search.getText().length());
StyleRange myStyledRange =
new StyleRange( cell.getText().toLowerCase().indexOf(text_Search.getText().toLowerCase()), text_Search.getText().length(), null, Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW));
StyleRange[] range = { myStyledRange };
cell.setStyleRanges(range);
//cell.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW));
}
Rectangle cellBounds = cell.getBounds();
cell.getControl().redraw(cellBounds.x, cellBounds.y, cellBounds.width,
cellBounds.height, true);
super.update(cell);
}
}
private class MyStyledCellLabelProvider extends StyledCellLabelProvider{
private final int columnIndex;
MyStyledCellLabelProvider(int columnIndex) {
this.columnIndex = columnIndex;
}
@Override
public void update(ViewerCell cell) {
if ( cell.getText().toLowerCase().contains(text_Search.getText().toLowerCase()) ) {
StyleRange myStyleRange =
new StyleRange( cell.getText().toLowerCase().indexOf(text_Search.getText().toLowerCase()), text_Search.getText().length(), null, Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW));
StyleRange[] styleRanges = { myStyleRange };
cell.setStyleRanges(styleRanges);
//cell.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_YELLOW));
}
else {
cell.setStyleRanges(null);
}
super.update(cell);
}
}
private SelectionAdapter createAdapterFor(final TableViewer tableViewer) {
return new SelectionAdapter() {
boolean b = true;
@Override
public void widgetSelected(SelectionEvent e) {
if (b) {
tableViewer.setFilters(new ViewerFilter[] { createFilterForViewer() });
for ( int i=0 ; i<tableViewerColumnList.size() ; i++) {
tableViewerColumnList.get(i).setLabelProvider(new MyStyledCellLabelProvider(i));
}
tableViewer.refresh();
b = false;
} else {
tableViewer.setFilters(new ViewerFilter[0]);
tableViewer.setLabelProvider(new TableLabelProvider());
b = true;
}
}
};
}
private ViewerFilter createFilterForViewer() {
return new ViewerFilter() {
@Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
boolean check = false;
for (Object cellData : ((Object[]) element)) {
check = cellData.toString().toLowerCase().contains(text_Search.getText().toLowerCase());
if (check) {
return check;
}
}
return check;
}
};
}
class TableData {
Object[] get(int numberOfRows, int numberOfColumns) {
Object[] tabledata = new Object[numberOfRows];
int random;
for (int r=0 ; r<numberOfRows ; r++) {
Object[] row = new Object[numberOfColumns];
for (int c = 0 ; c<numberOfColumns ; c++) {
random = (int)(Math.random() * numberOfRows + 1);
row[c] = "Item - "+ random + " - (" + r + "," + c + ")";
}
tabledata[r] = row;
}
return tabledata;
}
}
}