带有ViewerSorter和StyledCellLabelProvider的JFace TableViewer

时间:2014-09-01 15:56:00

标签: java eclipse swt jface tableviewer

在我的TableViewer中有一些TableViewerColumns。 我有一个文本小部件和一个按钮'搜索'。每当我点击搜索我想要为表格单元格文本着色 包含(匹配)文本小部件中的单词。我可以设置StyledCellLabelProvider来做到这一点 对于每个TableViewerColumn并覆盖更新方法,每个单元格文本的setStyleRanges都包含该单词。

我尝试将ColumnLabelProvider设置为每TableViewerColumn因为我需要覆盖getText方法' 但在这种情况下,覆盖update方法似乎不适用于setStyleRanges

最后我无法与StyledCellLabelProvider一起进行ViewerSorter工作,因为StyledCellLabelProvider没有 有一个getText方法。

有没有办法获得高级词汇,同时还能对表格进行排序?

2 个答案:

答案 0 :(得分:0)

使用您自己的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);
}

如果您没有使用类别,则可以省略代码的第一部分。

答案 1 :(得分:0)

我通过在StyledLabelProvider之后设置TableLabelProvider并刷新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;
        }

    }

}