Java tutorial
/******************************************************************************* * Copyright (c) 2011-2015 EclipseSource Muenchen GmbH and others. * * 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: * Johannes Faltermeier - initial API and implementation ******************************************************************************/ package org.eclipse.emfforms.spi.swt.treemasterdetail; import java.util.Collection; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emfforms.internal.swt.treemasterdetail.DefaultTreeViewerCustomization; import org.eclipse.emfforms.spi.swt.treemasterdetail.actions.MasterDetailAction; import org.eclipse.emfforms.spi.swt.treemasterdetail.util.CreateElementCallback; import org.eclipse.emfforms.spi.swt.treemasterdetail.util.RootObject; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.widgets.Composite; /** * The TreeViewerSWTBuilder is initialized with a default behavior. It offers methods to customize certain * aspects of a {@link org.eclipse.jface.viewers.TreeViewer TreeViewer}. * * @author Johannes Faltermeier * @since 1.8 * */ public class TreeViewerSWTBuilder { private final EditingDomain editingDomain; private final Composite composite; private final Object input; private final DefaultTreeViewerCustomization behaviour; /** * Default constructor. * * @param composite the parent composite * @param input the input object */ /* package */ TreeViewerSWTBuilder(Composite composite, Object input) { this.composite = composite; this.input = input; editingDomain = getEditingDomain(input); behaviour = new DefaultTreeViewerCustomization(); } /** * Use this method to set a custom {@link org.eclipse.jface.viewers.IContentProvider IContentProvider} on the tree * viewer. The default implementation will use * an {@link org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider AdapterFactoryContentProvider}. * * @param contentProvider the desired behavior * @return self */ public TreeViewerSWTBuilder customizeContentProvider(ContentProviderProvider contentProvider) { behaviour.setContentProvider(contentProvider); return this; } /** * Use this method to set a custom {@link org.eclipse.jface.viewers.IContentProvider IContentProvider} on the tree * viewer. If the content provider requires more dispose code than calling {@link IContentProvider#dispose()} use * {@link #customizeContentProvider(ContentProviderProvider)} instead. The default implementation will use * an {@link org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider AdapterFactoryContentProvider}. * * @param contentProvider the content provider to add * @return self */ public TreeViewerSWTBuilder customizeContentProvider(final IContentProvider contentProvider) { behaviour.setContentProvider(new ContentProviderProvider() { @Override public void dispose() { contentProvider.dispose(); } @Override public IContentProvider getContentProvider() { return contentProvider; } }); return this; } /** * Use this method to add a customized drag and drop behaviour to the tree or to remove drag and drop functionality. * The default implementation supports {@link org.eclipse.swt.dnd.DND#DROP_COPY DND#DROP_COPY}, * {@link org.eclipse.swt.dnd.DND#DROP_MOVE DND#DROP_MOVE} and {@link org.eclipse.swt.dnd.DND#DROP_LINK * DND#DROP_LINK} based * on EMF Edit. * * @param dnd the desired behavior * @return self */ public TreeViewerSWTBuilder customizeDragAndDrop(DNDProvider dnd) { behaviour.setDragAndDrop(dnd); return this; } /** * Use this method a add a custom {@link org.eclipse.jface.viewers.IBaseLabelProvider IBaseLabelProvider} to the * tree. The default implementation uses an * {@link org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider AdapterFactoryLabelProvider}. * * @param provider the desired behavior * @return self */ public TreeViewerSWTBuilder customizeLabelProvider(LabelProviderProvider provider) { behaviour.setLabelProvider(provider); return this; } /** * Use this method a add a custom {@link org.eclipse.jface.viewers.IBaseLabelProvider IBaseLabelProvider} to the * tree. If the label provider requires more dispose code than a call to {@link IBaseLabelProvider#dispose()} use * {@link #customizeLabelProvider(LabelProviderProvider)} instead. The default implementation uses an * {@link org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider AdapterFactoryLabelProvider}. * * @param provider the label provider to add * @return self */ public TreeViewerSWTBuilder customizeLabelProvider(final IBaseLabelProvider provider) { behaviour.setLabelProvider(new LabelProviderProvider() { @Override public void dispose() { provider.dispose(); } @Override public IBaseLabelProvider getLabelProvider() { return provider; } }); return this; } /** * Use this method to customize the {@link org.eclipse.swt.widgets.Menu Menu} which is shown when an element in the * tree is right-clicked. The * default implementation will offer menu entries to create new elements based on EMF Edit and to delete elements. * * @param menu the desired behavior * @return self */ public TreeViewerSWTBuilder customizeMenu(MenuProvider menu) { behaviour.setMenu(menu); return this; } /** * Use this method to customize the {@link org.eclipse.swt.widgets.Menu Menu} which is shown when an element in the * tree is right-clicked. Use this method to add additional menu entries. * * @param rightClickActions the additional right click actions which will be shown in the context menu * @return self * @since 1.8 */ public TreeViewerSWTBuilder customizeMenuItems(Collection<MasterDetailAction> rightClickActions) { behaviour.customizeMenu(rightClickActions); return this; } /** * Use this method to customize the {@link org.eclipse.swt.widgets.Menu Menu} which is shown when an element in the * tree is right-clicked. Use this method to influence the way new children are created. * * @param createElementCallback a callback which gets notified when a new child is created. this allows to veto the * creation or to change the object to be added * @return self * @since 1.8 */ public TreeViewerSWTBuilder customizeCildCreation(CreateElementCallback createElementCallback) { behaviour.customizeMenu(createElementCallback); return this; } /** * Use this method to customize the {@link org.eclipse.swt.widgets.Menu Menu} which is shown when an element in the * tree is right-clicked. Use this method to change the way elements are deleted. * * @param deleteActionBuilder the delete action which will be added to the context menu * @return self * @since 1.8 */ public TreeViewerSWTBuilder customizeDelete(DeleteActionBuilder deleteActionBuilder) { behaviour.customizeMenu(deleteActionBuilder); return this; } /** * Use this method to customize which element should be selected after the initial rendering. The default bahviour * is to select the root node, if it is displayed in the tree. * * @param selection the desired behavior * @return self */ public TreeViewerSWTBuilder customizeInitialSelection(InitialSelectionProvider selection) { behaviour.setInitialSelection(selection); return this; } /** * Use this method to create the {@link org.eclipse.jface.viewers.TreeViewer TreeViewer} which is part of the tree * master detail. The default * implementation creates a regular {@link org.eclipse.jface.viewers.TreeViewer TreeViewer} with an * {@link org.eclipse.jface.viewers.TreeViewer#setAutoExpandLevel(int) expand * level} of 3. * * @param tree the desired behavior * @return self */ public TreeViewerSWTBuilder customizeTree(TreeViewerBuilder tree) { behaviour.setTree(tree); return this; } /** * Use this method to add {@link org.eclipse.jface.viewers.ViewerFilter ViewerFilters} on the tree. The default * implementation does not add * filters. * * @param filters the filters to add * @return self */ public TreeViewerSWTBuilder customizeViewerFilters(final ViewerFilter[] filters) { behaviour.setViewerFilters(new ViewerFilterProvider() { @Override public ViewerFilter[] getViewerFilters() { return filters; } }); return this; } /** * Call this method after all desired customizations have been passed to the builder. The will create a new * {@link TreeMasterDetailComposite} with the desired customizations. * * @return the {@link TreeMasterDetailComposite} */ public TreeViewer create() { return create(behaviour, composite, editingDomain, input); } /** * @param input the input * @return the {@link EditingDomain} */ static EditingDomain getEditingDomain(Object input) { if (input instanceof Resource) { return AdapterFactoryEditingDomain.getEditingDomainFor(((Resource) input).getContents().get(0)); } else if (input instanceof RootObject) { return AdapterFactoryEditingDomain.getEditingDomainFor(RootObject.class.cast(input).getRoot()); } else { return AdapterFactoryEditingDomain.getEditingDomainFor(input); } } /** * Creates a {@link TreeViewer}. * * @param behaviour the {@link TreeViewerCustomization} * @param composite the parent {@link Composite} * @param editingDomain the {@link EditingDomain} * @param input the input * @return the viewer */ static TreeViewer create(TreeViewerCustomization behaviour, Composite composite, EditingDomain editingDomain, Object input) { final TreeViewer treeViewer = behaviour.createTree(composite); GridDataFactory.fillDefaults().grab(true, true).applyTo(treeViewer.getControl()); if (behaviour.hasDND()) { treeViewer.addDragSupport(behaviour.getDragOperations(), behaviour.getDragTransferTypes(), behaviour.getDragListener(treeViewer)); treeViewer.addDropSupport(behaviour.getDropOperations(), behaviour.getDropTransferTypes(), behaviour.getDropListener(editingDomain, treeViewer)); } treeViewer.setContentProvider(behaviour.getContentProvider()); treeViewer.setLabelProvider(behaviour.getLabelProvider()); treeViewer.setFilters(behaviour.getViewerFilters()); treeViewer.getControl().setMenu(behaviour.getMenu(treeViewer, editingDomain)); treeViewer.setInput(input); final EObject initialSelection = behaviour.getInitialSelection(input); if (initialSelection != null) { treeViewer.setSelection(new StructuredSelection(initialSelection), true); } return treeViewer; } }