Java tutorial
/******************************************************************************* * Copyright (c) 2014 Salesforce.com, inc.. * 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: * Salesforce.com, inc. - initial API and implementation ******************************************************************************/ package com.salesforce.ide.ui.editors.properysheets.widgets; import java.util.List; import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.CellEditor; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.EditingSupport; import org.eclipse.jface.viewers.ICellEditorListener; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.jface.viewers.TextCellEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import com.salesforce.ide.api.metadata.types.PackageVersion; import com.salesforce.ide.ui.editors.internal.utils.EditorMessages; /** * An editable table-based widget for Package Versions ({@link PackageVersion}. You cannot add/remove rows of the table. * You can only modify the version column of the table. This is just how Package Versions work currently. They are * added/removed automatically when you reference/dereference something in a managed package. * * @author nchen * */ public class PackageVersionWidget { private static final int TABLE_MIN_HEIGHT = 100; private static final int NAMESPACE_COL_WIDTH = 300; private static final int VERSION_COL_WIDTH = 100; private List<PackageVersion> packageVersions; private TableViewer tableViewer; private TableViewerColumn namespaceColumn; private TableViewerColumn versionColumn; private VersionColumnEditingSupport versionColumnEditingSupport; /* * Assumes that the parent composite is a two-column GridLayout */ public void addTo(Composite composite) { tableViewer = new TableViewer(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER); tableViewer.setContentProvider(ArrayContentProvider.getInstance()); tableViewer.getTable().setHeaderVisible(true); GridData gridData = new GridData(); gridData.verticalAlignment = GridData.FILL; gridData.minimumHeight = TABLE_MIN_HEIGHT; gridData.horizontalSpan = 2; gridData.horizontalAlignment = GridData.FILL; gridData.grabExcessHorizontalSpace = true; gridData.grabExcessVerticalSpace = true; tableViewer.getControl().setLayoutData(gridData); namespaceColumn = new TableViewerColumn(tableViewer, SWT.BORDER); namespaceColumn.getColumn().setWidth(NAMESPACE_COL_WIDTH); namespaceColumn.getColumn().setText(EditorMessages.getString("PackageVersionWidget.NamespaceColumn")); //$NON-NLS-1$ namespaceColumn.setLabelProvider(new NamespaceLabelProvider()); versionColumn = new TableViewerColumn(tableViewer, SWT.BORDER); versionColumn.getColumn().setWidth(VERSION_COL_WIDTH); versionColumn.getColumn().setText(EditorMessages.getString("PackageVersionWidget.VersionColumn")); //$NON-NLS-1$ versionColumn.setLabelProvider(new VersionLabelProvider()); versionColumnEditingSupport = new VersionColumnEditingSupport(tableViewer); versionColumn.setEditingSupport(versionColumnEditingSupport); } public List<PackageVersion> getPackageVersions() { return packageVersions; } public void addListener(ICellEditorListener listener) { versionColumnEditingSupport.cellEditor.addListener(listener); } public void removeListener(ICellEditorListener listener) { versionColumnEditingSupport.cellEditor.removeListener(listener); } public void setPackageVersions(List<PackageVersion> packageVersions) { this.packageVersions = packageVersions; tableViewer.setInput(this.packageVersions); tableViewer.refresh(); } // This is non-final and non-private so we can unit test it. static class VersionColumnEditingSupport extends EditingSupport { private TextCellEditor cellEditor; private TableViewer viewer; static Pattern packageFormatWithDecimal = Pattern.compile("(\\d+)(.\\d+)?"); //$NON-NLS-1$ private VersionColumnEditingSupport(TableViewer viewer) { super(viewer); this.viewer = viewer; cellEditor = new TextCellEditor(viewer.getTable()); } @Override protected void setValue(Object element, Object value) { PackageVersion pv = (PackageVersion) element; updateValueIfPossible(pv, value); viewer.update(element, null); } protected PackageVersion updateValueIfPossible(PackageVersion pv, Object value) { String number = (String) value; Matcher matcher = packageFormatWithDecimal.matcher(number); if (matcher.matches()) { // Reset the values first (especially in case there is no decimal part, we want to default to 0) pv.setMajorNumber(0); pv.setMinorNumber(0); Scanner scanner = new Scanner(number).useDelimiter("\\."); //$NON-NLS-1$ // Whole part - must exist for it to pass the matcher pv.setMajorNumber(scanner.nextInt()); if (scanner.hasNextInt()) { // Decimal part, user might just not put it, then default to 0 pv.setMinorNumber(scanner.nextInt()); } } return pv; } @Override protected Object getValue(Object element) { PackageVersion pv = (PackageVersion) element; return String.format("%d.%d", pv.getMajorNumber(), pv.getMinorNumber()); //$NON-NLS-1$ } @Override protected CellEditor getCellEditor(Object element) { return cellEditor; } @Override protected boolean canEdit(Object element) { return true; } } private static final class NamespaceLabelProvider extends ColumnLabelProvider { @Override public String getText(Object element) { PackageVersion pv = (PackageVersion) element; return pv.getNamespace(); } } private static final class VersionLabelProvider extends ColumnLabelProvider { @Override public String getText(Object element) { PackageVersion pv = (PackageVersion) element; return String.format("%d.%d", pv.getMajorNumber(), pv.getMinorNumber()); //$NON-NLS-1$ } } }