Java tutorial
/* uDig-Spatial Operations plugins * http://b5m.gipuzkoa.net * (C) 2006, Diputacin Foral de Gipuzkoa, Ordenacin Territorial. * * 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; * version 2.1 of the License. * * 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. */ package es.axios.udig.spatialoperations.ui.view; import java.util.ArrayList; import java.util.List; import java.util.Observable; import java.util.Observer; import java.util.Set; import java.util.logging.Logger; import net.refractions.udig.project.IMap; import net.refractions.udig.project.ui.render.displayAdapter.ViewportPane; import net.refractions.udig.project.ui.tool.IToolContext; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.custom.ViewForm; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import es.axios.udig.spatialoperations.internal.preferences.Preferences; import es.axios.udig.spatialoperations.ui.parameters.ISOBuilder; import es.axios.udig.spatialoperations.ui.parameters.ISOCommand; import es.axios.udig.spatialoperations.ui.parameters.ISOTopParamsPresenter; import es.axios.udig.spatialoperations.ui.parameters.SOContext; import es.axios.udig.spatialoperations.ui.parameters.SpatialOperationDefaultBuilder; import es.axios.udig.ui.commons.message.InfoMessage; /** * Frame to present all spatial operation . * * <p> * This composite defines the layout for the following widgets: * * <ul> * <li>Operation selection * <li>Demonstration area * <li>Information area * <li>Parameters area * <li>Perform Command * </ul> * * </p> * * @author Mauricio Pazos (www.axios.es) * @author Aritz Davila (www.axios.es) * @since 1.1.0 */ final public class SOComposite extends Composite implements ISOPresenter, Observer { private static final Logger LOGGER = Logger.getLogger(SOComposite.class.getName()); private static final String SPATIAL_OPERATION_EXTENSIONS_ID = "es.axios.udig.spatialoperations.ui"; //$NON-NLS-1$ private static final int GRID_DATA_1_WIDTH_HINT = 125; /** Used as key in the data map associated to spatial operation's tree item */ private static final String SO_CONTEXT_KEY = "ctx"; //$NON-NLS-1$ /** Spatial operation id 's key in the data map */ private static final String SO_ID_KEY = "id"; //$NON-NLS-1$ /** Spatial operation name's key in the data map related with a tree item */ private static final String SO_NAME_KEY = "name"; //$NON-NLS-1$ /** spatial operation names presentation */ private TreeViewer treeView = null; private Composite compositeSOSelection = null; private Composite compositeSOParameters = null; private ISOTopParamsPresenter currentOpPresenter = null; private Composite compositeInformation = null; private CLabel messageImage = null; private CLabel messageText = null; private CLabel messageOperation = null; private StackLayout stackSOParamsLayout; private IToolContext udigContext = null; private SOView soView = null; private ViewForm viewForm; private Composite compositeTree = null; private SashForm sashForm = null; private TreeNode treeOperations; public SOComposite(SOView view, Composite parent, int style) { super(parent, style); // set the view which contains the observer setSOView(view); view.setSpatialOperationPresenter(this); createContent(); } /** * Opens this widget populating its widgets */ public void open() { // if nothing selected if (this.treeView.getTree().getSelection().length == 0) { displayOperation(null); } else { displayOperation(this.treeView.getTree().getSelection()[0].getText()); } } private void createContent() { sashForm = new SashForm(this, SWT.NONE); createCompositeSOSelection(sashForm); viewForm = new ViewForm(sashForm, SWT.NONE); viewForm.setLayout(new FillLayout()); Composite soComposite = createCompositeSOlegend(viewForm); viewForm.setTopLeft(soComposite); Composite paramsComposite = createCompositeSOParameters(viewForm); viewForm.setContent(paramsComposite); // must go after populating the sash whit composites sashForm.setWeights(new int[] { 18, 82 }); } /** * This method initializes compositeSOSelection * */ private Composite createCompositeSOSelection(final Composite parent) { GridLayout layout = new GridLayout(); layout.numColumns = 1; GridData gridData = new GridData(); gridData.horizontalAlignment = GridData.FILL; gridData.grabExcessHorizontalSpace = true; gridData.grabExcessVerticalSpace = true; gridData.widthHint = 150; gridData.verticalAlignment = GridData.FILL; compositeSOSelection = new Composite(parent, SWT.BORDER); compositeSOSelection.setLayoutData(gridData); compositeSOSelection.setLayout(layout); createCompositeCommand(compositeSOSelection); return compositeSOSelection; } private Composite createCompositeSOlegend(final Composite parent) { GridLayout layout = new GridLayout(); layout.numColumns = 1; GridData gridData = new GridData(); gridData.horizontalAlignment = GridData.FILL; gridData.grabExcessHorizontalSpace = true; gridData.grabExcessVerticalSpace = false; gridData.minimumHeight = 300; gridData.minimumWidth = 500; gridData.verticalAlignment = SWT.CENTER; compositeSOSelection = new Composite(parent, SWT.BORDER); compositeSOSelection.setLayoutData(gridData); compositeSOSelection.setLayout(layout); createCompositeInformation(compositeSOSelection); return compositeSOSelection; } /** * This method initializes compositeCommand * */ private void createCompositeCommand(final Composite parent) { GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 1; GridData gridData4 = new GridData(); gridData4.horizontalAlignment = SWT.FILL; gridData4.grabExcessHorizontalSpace = true; gridData4.grabExcessVerticalSpace = true; gridData4.verticalAlignment = SWT.FILL; gridData4.widthHint = GRID_DATA_1_WIDTH_HINT; compositeTree = new Composite(parent, SWT.NONE); compositeTree.setLayoutData(gridData4); compositeTree.setLayout(gridLayout); treeView = new TreeViewer(compositeTree, SWT.FILL); treeView.setContentProvider(new ITreeContentProvider() { public Object[] getChildren(Object parentElement) { return ((TreeNode) parentElement).getChildren().toArray(); } public Object getParent(Object element) { return ((TreeNode) element).getParent(); } public boolean hasChildren(Object element) { return ((TreeNode) element).getChildren().size() > 0; } public Object[] getElements(Object inputElement) { return ((TreeNode) inputElement).getChildren().toArray(); } public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } }); treeView.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { TreeItem[] index = treeView.getTree().getSelection(); if (index.length == 0) { return; } TreeItem selectedItem = treeView.getTree().getSelection()[0]; switchOperation(selectedItem); } }); treeView.setInput(createTree()); treeView.getTree().setLayoutData(gridData4); } /** * Create a tree on the treeviewer */ private TreeNode createTree() { treeOperations = new TreeNode("General"); //$NON-NLS-1$ return treeOperations; } class TreeNode { private String name; private List<TreeNode> children = new ArrayList<TreeNode>(); private TreeNode parent; public TreeNode(String n) { name = n; } protected Object getParent() { return parent; } public TreeNode addChild(TreeNode child) { children.add(child); child.parent = this; return this; } public List<TreeNode> getChildren() { return children; } @Override public String toString() { return name; } } /** * Load operations' images for each operation register in combo * * @return ImageRegistry */ private ImageRegistry createImageRegistry() { ImageRegistry registry = new ImageRegistry(this.getDisplay()); for (int i = 0; i < this.treeView.getTree().getItemCount(); i++) { TreeItem item = this.treeView.getTree().getItem(i); String opId = (String) item.getData(SO_ID_KEY); String imgFile = "images/" + opId + ".gif"; //$NON-NLS-1$ //$NON-NLS-2$ registry.put(opId, ImageDescriptor.createFromFile(SOComposite.class, imgFile)); } return registry; } /** * This method initializes compositeInformation * */ private void createCompositeInformation(final Composite parent) { GridData gridData6 = new GridData(); gridData6.horizontalAlignment = GridData.FILL; gridData6.grabExcessHorizontalSpace = true; gridData6.grabExcessVerticalSpace = true; gridData6.verticalAlignment = GridData.FILL; compositeInformation = new Composite(parent, SWT.NONE); GridLayout gridLayout = new GridLayout(3, false); compositeInformation.setLayoutData(gridData6); compositeInformation.setLayout(gridLayout); this.messageImage = new CLabel(compositeInformation, SWT.NONE); GridData gridData7 = new GridData(); gridData7.horizontalAlignment = GridData.BEGINNING; gridData7.minimumWidth = 30; gridData7.widthHint = 30; this.messageImage.setLayoutData(gridData7); this.messageOperation = new CLabel(compositeInformation, SWT.NONE); GridData gridData5 = new GridData(); gridData5.widthHint = 70; this.messageOperation.setLayoutData(gridData5); this.messageText = new CLabel(compositeInformation, SWT.NONE); GridData gridData8 = new GridData(); gridData8.horizontalAlignment = GridData.FILL; gridData8.grabExcessHorizontalSpace = true; gridData8.grabExcessVerticalSpace = true; gridData8.verticalAlignment = GridData.FILL; this.messageText.setLayoutData(gridData8); // this.messageText.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); this.messageText.setFont(JFaceResources.getDialogFont()); } /** * This method initializes compositeSOParameters */ private Composite createCompositeSOParameters(final Composite parent) { ScrolledComposite scrollComposite = new ScrolledComposite(parent, SWT.NONE | SWT.H_SCROLL | SWT.V_SCROLL); scrollComposite.setLayout(new FillLayout()); // creates the container for controls in scroll composite this.compositeSOParameters = new Composite(scrollComposite, SWT.NONE); this.stackSOParamsLayout = new StackLayout(); compositeSOParameters.setLayout(this.stackSOParamsLayout); // adds the parameters container to scroll composite scrollComposite.setContent(compositeSOParameters); scrollComposite.setExpandHorizontal(true); scrollComposite.setExpandVertical(true); scrollComposite.setMinHeight(300); createOperationParamsPresenters(this.compositeSOParameters); return scrollComposite; } /** * Creates the default spatial operations and extensions * * @param paramsContainer */ private void createOperationParamsPresenters(final Composite paramsContainer) { createSpatialOperations(paramsContainer, new SpatialOperationDefaultBuilder()); createSpatialOperationExtensions(paramsContainer); createImageRegistry(); } /** * Creates the spatial operations and establish the association with the * spatial operation framework * * @param paramsContainer */ private void createSpatialOperations(Composite paramsContainer, ISOBuilder soBuilder) { soBuilder.build(paramsContainer); Set<Object[]> soList = soBuilder.getResult(); if (soList.isEmpty()) { final String msg = "The builder " + soBuilder.getClass().getName() + " has not created any spatial operation."; LOGGER.severe(msg); } // associates the spatial operations components with the view for (Object[] soComponent : soList) { SOContext ctx = new SOContext(this, (ISOTopParamsPresenter) soComponent[0], (ISOCommand) soComponent[1], this.soView); addInOperationsPanel(this.treeView.getTree(), ctx); } } /** * Loads the spatial operation extensions from each provider plug-in . * * @param paramsContainer */ private void createSpatialOperationExtensions(Composite paramsContainer) { try { IConfigurationElement[] config = Platform.getExtensionRegistry() .getConfigurationElementsFor(SPATIAL_OPERATION_EXTENSIONS_ID); for (IConfigurationElement e : config) { // creates the executable builder for this spatial operation // extension Object builder = e.createExecutableExtension("SOBuilder"); createSpatialOperations(paramsContainer, (ISOBuilder) builder); } } catch (Exception ex) { ex.printStackTrace(); LOGGER.severe(ex.getMessage()); } } /** * Adds operations to the tree * * @param operationsTree * * @param paramsPresenter */ private void addInOperationsPanel(final Tree operationsTree, final SOContext ctx) { ISOTopParamsPresenter paramsPresenter = ctx.getTopPresenter(); final String opID = paramsPresenter.getOperationID(); final String opName = paramsPresenter.getOperationName(); TreeItem treeItem = new TreeItem(operationsTree, SWT.NONE); treeItem.setText(opName); treeItem.setData(SO_ID_KEY, opID); treeItem.setData(SO_NAME_KEY, opName); treeItem.setData(SO_CONTEXT_KEY, ctx); // sets the tree item image. Image image = paramsPresenter.getImage(); treeItem.setImage(image); paramsPresenter.visible(false); } /** * Shows operation's parameters of the selected operation. The current * operation will be invisible * * @param opSelected */ private void switchOperation(final TreeItem selectedItem) { // disable the runButton this.soView.enableRunButton(false); if (this.currentOpPresenter != null) { this.currentOpPresenter.close(); } SOContext ctx = (SOContext) selectedItem.getData(SO_CONTEXT_KEY); this.currentOpPresenter = ctx.getTopPresenter(); // sets the operation's tool tip with initial message String msg = this.currentOpPresenter.getToolTipText(); this.treeView.getTree().setToolTipText(msg); // pulls up the parameter's presentation for the selected operation Composite paramsPresenter = (Composite) this.currentOpPresenter; this.stackSOParamsLayout.topControl = paramsPresenter; paramsPresenter.getParent().layout(); currentOpPresenter.setContext(udigContext); currentOpPresenter.visible(true); IMap currentMap = null; if (udigContext != null) { currentMap = udigContext.getMap(); } if (currentMap != null) { currentOpPresenter.open(); } else { currentOpPresenter.close(); } } /** * Sets the new context. Map deleted, added or layer list changes * * @param newContext */ public void setContext(final IToolContext newContext) { this.udigContext = newContext; this.currentOpPresenter.setContext(newContext); } /** * Shows the message in the standard information area */ public void displayMessage(final InfoMessage message) { assert message != null; // The following sentences does a filter of those obvious messages InfoMessage filteredMessage = message; if (InfoMessage.Type.INFORMATION.equals(message.getType())) { filteredMessage = this.currentOpPresenter.getDefaultMessage(); } // then shows important, warnings and fail messages String opName; if (this.treeView.getTree().getSelection().length == 0) { opName = this.treeView.getTree().getItem(0).getText(); } else { opName = this.treeView.getTree().getSelection()[0].getText(); } // shows the message this.compositeInformation.setVisible(true); this.messageImage.setImage(filteredMessage.getImage()); this.messageOperation.setText(opName); this.messageText.setToolTipText(filteredMessage.getText()); this.messageText.setText(filteredMessage.getText()); } /** * enable/disable this composite */ @Override public void setEnabled(boolean enabled) { super.setEnabled(enabled); this.treeView.getTree().setEnabled(enabled); this.compositeSOParameters.setEnabled(enabled); this.currentOpPresenter.setEnabled(enabled); } /** * Executes the operation associated to selected control. * */ public void executeOperation() { setEnabled(false); // sets the wait cursor and disables this panel ViewportPane pane = this.udigContext.getViewportPane(); Display display = getDisplay(); pane.setCursor(display.getSystemCursor(SWT.CURSOR_WAIT)); this.currentOpPresenter.executeCommand(); pane.setCursor(null); setEnabled(true); } /** * Clear the inputs values */ public void initializeInputs() { if (this.currentOpPresenter == null) { return; } this.currentOpPresenter.clear(); InfoMessage message = this.currentOpPresenter.getMessage(); this.displayMessage(message); } /** * Select an operation if there isn't one selected and switch to that * operation. */ private void displayOperation(String treeName) { if (treeName == null) { treeName = this.treeView.getTree().getItem(0).getText(); this.treeView.getTree().setSelection(this.treeView.getTree().getItem(0)); } TreeItem selected = this.treeView.getTree().getSelection()[0]; switchOperation(selected); } /** * The view whit the observer * * @param view */ private void setSOView(final SOView view) { assert view != null; this.soView = view; } /** * show/hide the demo image for all presenters in the spatial */ public void switchShowHide() { // switch the preverence value boolean visible = !Preferences.isDemoVisible(); Preferences.setDemoVisible(visible); // switch show or hide all demo presenters for (int i = 0; i < this.treeView.getTree().getItemCount(); i++) { TreeItem item = this.treeView.getTree().getItem(i); Object itemData = item.getData(SO_CONTEXT_KEY); SOContext ctx = (SOContext) itemData; ISOTopParamsPresenter presenter = ctx.getTopPresenter(); presenter.switchShowHideDemo(visible); } this.sashForm.layout(); } public void update(Observable o, Object arg) { if (this.currentOpPresenter == null) { return; } InfoMessage message = this.currentOpPresenter.getCommand().getMessage(); displayMessage(message); } } // @jve:decl-index=0:visual-constraint="10,10"