Java tutorial
// ============================================================================ // // Copyright (C) 2002-2011 David Schneider, Lars Kdderitzsch, Fabrice Bellingard // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // ============================================================================ package com.tocea.scertify.eclipse.scertifycode.ui.util.table; import java.text.Collator; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.viewers.ColumnPixelData; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ControlListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import com.tocea.scertify.eclipse.scertifycode.ui.Activator; /** * This subclass of <code>TableViewer</code> adds easier sorting support and * support for storing table settings (column width, sorter state). * * @author Lars Kdderitzsch */ public class EnhancedTableViewer extends TableViewer { // // constants // /** * Listener for header clicks and resize events. * * @author Lars Kdderitzsch */ private class TableListener implements SelectionListener, ControlListener { public void controlMoved(ControlEvent e) { // NOOP } public void controlResized(ControlEvent e) { if (e.getSource() instanceof TableColumn) { EnhancedTableViewer.this.saveState(); } } public void widgetDefaultSelected(SelectionEvent e) { // NOOP } public void widgetSelected(SelectionEvent e) { if (e.getSource() instanceof TableColumn) { final TableColumn col = (TableColumn) e.getSource(); final Table table = col.getParent(); final int colIndex = table.indexOf(col); if (colIndex == EnhancedTableViewer.this.mSortedColumnIndex) { EnhancedTableViewer.this.mSortDirection = EnhancedTableViewer.this.mSortDirection * DIRECTION_REVERSE; } else { EnhancedTableViewer.this.mSortedColumnIndex = colIndex; EnhancedTableViewer.this.mSortDirection = DIRECTION_FORWARD; } EnhancedTableViewer.this.resort(); EnhancedTableViewer.this.saveState(); } } } /** * Sorter implementation that uses the values provided by the comparable * provider to sort the table. * * @author Lars Kdderitzsch */ private class TableSorter extends ViewerSorter { /** * {@inheritDoc} */ public int compare(Viewer viewer, Object e1, Object e2) { final Comparable c1 = EnhancedTableViewer.this.mComparableProvider.getComparableValue(e1, EnhancedTableViewer.this.mSortedColumnIndex); final Comparable c2 = EnhancedTableViewer.this.mComparableProvider.getComparableValue(e2, EnhancedTableViewer.this.mSortedColumnIndex); int compareResult = 0; // support for string collation if (c1 instanceof String && c2 instanceof String) { compareResult = COLLATOR.compare(c1, c2); } else { compareResult = c1.compareTo(c2); } // take sort direction into account return compareResult * EnhancedTableViewer.this.mSortDirection; } } /** Key for the column index in the persistence store. */ private static final String TAG_COLUMN_INDEX = "sortColumn"; //$NON-NLS-1$ /** Key for the sort direction in the persistence store. */ private static final String TAG_SORT_DIRECTION = "sortDirection"; //$NON-NLS-1$ /** Key for the widths in the persistence store. */ private static final String TAG_COLUMN_WIDTH = "colWidth"; //$NON-NLS-1$ /** Key for the selection index in the persistence store. */ private static final String TAG_CURRENT_SELECTION = "selectedRow"; //$NON-NLS-1$ /** Integer constant for the forward sort direction value. */ private static final int DIRECTION_FORWARD = 1; // // attributes // /** Integer constant for the reverse sort direction value. */ private static final int DIRECTION_REVERSE = -1; /** Collator to support natural sorting of strings. */ private static final Collator COLLATOR = Collator.getInstance(Activator.getPlatformLocale()); /** the comparable provider for sorting support. */ private ITableComparableProvider mComparableProvider; /** the settings provider. */ private ITableSettingsProvider mSettingsProvider; /** The index of the current sorted column. */ private int mSortedColumnIndex; // // constructors // /** The sort direction. */ private int mSortDirection = DIRECTION_FORWARD; /** The table listener. */ private final TableListener mTableListener = new TableListener(); /** * Creates the EnhancedTableViewer within the given parent composite. * * @param parent * parent composite */ public EnhancedTableViewer(Composite parent) { super(parent); } // // methods // /** * Creates the EnhancedTableViewer for the given parent and style. * * @param parent * parent composite * @param style * the style */ public EnhancedTableViewer(Composite parent, int style) { super(parent, style); } /** * Creates the EnhancedTableViewer for the given table. * * @param table * the table to create the viewer for */ public EnhancedTableViewer(Table table) { super(table); // table.setLayout(new TableLayout() // {}); } /** * Returns the comparable provider. * * @return the comparable provider */ public ITableComparableProvider getTableComparableProvider() { return this.mComparableProvider; } /** * Returns the settings provider. * * @return the settings provider */ public ITableSettingsProvider getTableSettingsProvider() { return this.mSettingsProvider; } /** * This method installs the enhancements over the standard TableViewer. This * method must be called only after all columns are set up for the * associated table. */ public void installEnhancements() { this.getTable().removeSelectionListener(this.mTableListener); final TableColumn[] columns = this.getTable().getColumns(); for (final TableColumn column : columns) { column.removeSelectionListener(this.mTableListener); column.removeControlListener(this.mTableListener); } this.restoreState(); this.getTable().addSelectionListener(this.mTableListener); for (final TableColumn column : columns) { column.addSelectionListener(this.mTableListener); column.addControlListener(this.mTableListener); } } /** * Helper method to resort the table viewer. */ private void resort() { this.getTable().getDisplay().asyncExec(new Runnable() { public void run() { if (!EnhancedTableViewer.this.getControl().isDisposed()) { EnhancedTableViewer.this.getControl().setRedraw(false); EnhancedTableViewer.this.refresh(false); EnhancedTableViewer.this.getControl().setRedraw(true); } } }); } /** * Restores the sorting state from the dialog settings. */ private void restoreState() { final IDialogSettings settings = this.mSettingsProvider != null ? this.mSettingsProvider.getTableSettings() : null; if (settings == null) { return; } try { this.mSortedColumnIndex = settings.getInt(TAG_COLUMN_INDEX); } catch (final NumberFormatException e) { this.mSortedColumnIndex = 0; } try { this.mSortDirection = settings.getInt(TAG_SORT_DIRECTION); } catch (final NumberFormatException e) { this.mSortDirection = DIRECTION_FORWARD; } final TableLayout layout = new TableLayout(); boolean allColumnsHaveStoredData = true; // store the column widths final TableColumn[] columns = this.getTable().getColumns(); for (int i = 0, size = columns.length; i < size; i++) { try { final int width = settings.getInt(TAG_COLUMN_WIDTH + i); columns[i].setWidth(width); layout.addColumnData(new ColumnPixelData(width)); } catch (final NumberFormatException e) { // probably a new column allColumnsHaveStoredData = false; } } // if no all columns have stored width data then probably a new // columns has been added, in this case fall back to the default // weighted layout if (allColumnsHaveStoredData) { this.getTable().setLayout(layout); } // restore the selection try { this.getTable().select(settings.getInt(TAG_CURRENT_SELECTION)); } catch (final NumberFormatException e) { // NOOP } this.resort(); } /** * Saves the sorting state to the dialog settings. */ private void saveState() { final IDialogSettings settings = this.mSettingsProvider != null ? this.mSettingsProvider.getTableSettings() : null; if (settings == null) { return; } settings.put(TAG_COLUMN_INDEX, this.mSortedColumnIndex); settings.put(TAG_SORT_DIRECTION, this.mSortDirection); // store the column widths final TableColumn[] columns = this.getTable().getColumns(); for (int i = 0, size = columns.length; i < size; i++) { final int width = columns[i].getWidth(); if (width > 0) { settings.put(TAG_COLUMN_WIDTH + i, width); } } // store the selection settings.put(TAG_CURRENT_SELECTION, this.getTable().getSelectionIndex()); } /** * Sets the comparable provider for this table. * * @param comparableProvider * the comparable provider */ public void setTableComparableProvider(ITableComparableProvider comparableProvider) { this.mComparableProvider = comparableProvider; if (this.mComparableProvider != null) { this.setSorter(new TableSorter()); } else { this.setSorter(null); } } /** * Sets the settings provider. * * @param settingsProvider * the settings provider */ public void setTableSettingsProvider(ITableSettingsProvider settingsProvider) { this.mSettingsProvider = settingsProvider; } }