/******************************************************************************* * Copyright (c) 2008 Ralf Ebert * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Ralf Ebert - initial API and implementation *******************************************************************************/ package de.ralfebert.rcputils.tables; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.CellLabelProvider; import org.eclipse.jface.viewers.ColumnPixelData; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.TableColumn; import de.ralfebert.rcputils.properties.IValue; import de.ralfebert.rcputils.properties.IValueFormatter; import de.ralfebert.rcputils.properties.PropertyCellLabelProvider; import de.ralfebert.rcputils.properties.PropertyEditingSupport; import de.ralfebert.rcputils.properties.PropertyValue; import de.ralfebert.rcputils.tables.format.Formatter; import de.ralfebert.rcputils.tables.format.StringValueFormatter; import de.ralfebert.rcputils.tables.sort.SortColumnComparator; /** * ColumnBuilder is responsible to build a column for {@link TableViewerBuilder} * Methods are chainable so you can construct table columns in a single line. * After customizing the column by calling methods, call build() once to create * the actual column. * * @author Ralf Ebert <info@ralfebert.de> */ @SuppressWarnings("unchecked") public class ColumnBuilder { private final TableViewerBuilder builder; private final String columnHeaderText; private IValue valueHandler; private IValueFormatter valueFormatter; private ICellFormatter cellFormatter; private CellLabelProvider customLabelProvider; private Integer widthPixel; private Integer widthPercent; private int align = SWT.LEFT; private CellEditor editor; private IValue sortBy; private boolean defaultSort; private IValueFormatter editorFormat; ColumnBuilder(TableViewerBuilder builder, String columnHeaderText) { this.builder = builder; this.columnHeaderText = columnHeaderText; } /** * Binds this column to the given property. */ public ColumnBuilder bindToProperty(String propertyName) { return bindToValue(new PropertyValue(propertyName)); } /** * Binds the column to an arbitrary value. */ public ColumnBuilder bindToValue(IValue valueHandler) { this.valueHandler = valueHandler; return this; } /** * Sets a formatter for this column that is responsible to convert the value * into a String. The 'parse' method of the CellFormatter is not required * for this. See {@link Formatter} for commonly-used formatters. */ public ColumnBuilder format(IValueFormatter valueFormatter) { this.valueFormatter = valueFormatter; return this; } /** * A cell formatter allows to format the cell besides the textual value, for * example to customize colors or set images. */ public ColumnBuilder format(ICellFormatter cellFormatter) { this.cellFormatter = cellFormatter; return this; } /** * If your column is not text based (for example a column with images that * are owner-drawn), you can use a custom CellLabelProvider instead of a * value and a value formatter. */ public ColumnBuilder setCustomLabelProvider(CellLabelProvider customLabelProvider) { this.customLabelProvider = customLabelProvider; return this; } /** * Sets column width in percent */ public ColumnBuilder setPercentWidth(int width) { this.widthPercent = width; return this; } /** * Sets column width in pixel */ public ColumnBuilder setPixelWidth(int width) { this.widthPixel = width; return this; } /** * Sets alignment of column cell texts to be centered. */ public ColumnBuilder alignCenter() { this.align = SWT.CENTER; return this; } /** * Sets alignment of column cell texts to be right-aligned. */ public ColumnBuilder alignRight() { this.align = SWT.RIGHT; return this; } /** * Makes this column editable. Using this method you get a text editor * without any formatting applied, to the value type needs to be String. */ public ColumnBuilder makeEditable() { return makeEditable(new TextCellEditor(builder.getTable()), StringValueFormatter.INSTANCE); } /** * Makes this column editable. Using this method you get a text editor. The * given valueFormatter will be responsible for formatting the value to a * String and parsing it back to a new value. */ public ColumnBuilder makeEditable(IValueFormatter valueFormatter) { return makeEditable(new TextCellEditor(builder.getTable()), valueFormatter); } /** * Makes the column cells editable using a custom cell editor. No formatting * is applied, the editor will see the value as it is. */ public ColumnBuilder makeEditable(CellEditor cellEditor) { return makeEditable(cellEditor, null); } /** * Makes the column cells editable using a custom cell editor. The given * valueFormatter will be responsible for formatting the value for the * editor and converting it back to a new value. */ public ColumnBuilder makeEditable(CellEditor cellEditor, IValueFormatter valueFormatter) { if (cellEditor.getControl().getParent() != builder.getTable()) throw new RuntimeException("Parent of cell editor needs to be the table!"); this.editor = cellEditor; this.editorFormat = valueFormatter; return this; } /** * Sets a custom value to sort by. Implement yourself our use PropertyValue * to sort by a custom property value. */ public ColumnBuilder sortBy(IValue sortBy) { this.sortBy = sortBy; return this; } /** * Sets this column as default sort column */ public ColumnBuilder useAsDefaultSortColumn() { this.defaultSort = true; return this; } /** * Builds the column and returns the TableViewerColumn */ public TableViewerColumn build() { // create column TableViewerColumn viewerColumn = new TableViewerColumn(builder.getTableViewer(), align); TableColumn column = viewerColumn.getColumn(); column.setText(columnHeaderText); // set label provider if (customLabelProvider != null) { if (cellFormatter != null) { throw new RuntimeException("If you specify a custom label provider, it is not allowed " + "to specify a cell formatter. You need to do the formatting in your labelprovider!"); } viewerColumn.setLabelProvider(customLabelProvider); } else { viewerColumn.setLabelProvider(new PropertyCellLabelProvider(valueHandler, valueFormatter, cellFormatter)); } // activate column sorting if (sortBy == null) { sortBy = valueHandler; } if (sortBy != null) { column.setData(SortColumnComparator.SORT_BY, sortBy); column.addSelectionListener(builder.getSortSelectionListener()); if (defaultSort) { builder.getTable().setSortColumn(column); builder.getTable().setSortDirection(SWT.UP); } } // set column layout data if (widthPixel != null && widthPercent != null) { throw new RuntimeException("You can specify a width in pixel OR in percent, but not both!"); } if (widthPercent == null) { // default width of 100px if nothing specified builder.getTableLayout().setColumnData(column, new ColumnPixelData(widthPixel == null ? 100 : widthPixel)); } else { builder.getTableLayout().setColumnData(column, new ColumnWeightData(widthPercent)); } // set editing support if (editor != null) { if (valueHandler == null) { throw new RuntimeException( "makeEditable() requires that the column is bound to some value using bindTo...()"); } viewerColumn.setEditingSupport(new PropertyEditingSupport(builder.getTableViewer(), valueHandler, editorFormat, editor)); } return viewerColumn; } }