Java tutorial
/* Image Georeferencing * * Axios Engineering * http://www.axios.es * * (C) 2011, Axios Engineering S.L. (Axios) * Axios agrees to licence under Lesser General Public License (LGPL). * * 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.georeferencing.internal.ui.coordinatepanel; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Observable; import java.util.Observer; import java.util.Set; import net.refractions.udig.project.IMap; import net.refractions.udig.project.ui.ApplicationGIS; import net.refractions.udig.project.ui.tool.IToolContext; import net.refractions.udig.project.ui.tool.Tool; import org.eclipse.jface.action.IAction; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.custom.TableEditor; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.ScrollBar; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.opengis.referencing.crs.CoordinateReferenceSystem; import com.vividsolutions.jts.geom.Coordinate; import es.axios.udig.georeferencing.internal.i18n.Messages; import es.axios.udig.georeferencing.internal.process.MarkModel; import es.axios.udig.georeferencing.internal.process.MarkModel.MarkModelChange; import es.axios.udig.georeferencing.internal.ui.GeoReferencingCommand; import es.axios.udig.georeferencing.internal.ui.GeoReferencingComposite; import es.axios.udig.georeferencing.internal.ui.GeoreferencingCommandEventChange; import es.axios.udig.georeferencing.internal.ui.InputEvent; import es.axios.udig.georeferencing.internal.ui.MainComposite; import es.axios.udig.georeferencing.internal.ui.MouseSelectionListener; import es.axios.udig.georeferencing.internal.ui.coordinatepanel.tools.AddCoordinateTool; import es.axios.udig.georeferencing.internal.ui.coordinatepanel.tools.CapturedCoordinateListener; import es.axios.udig.georeferencing.internal.ui.coordinatepanel.tools.DeleteCoordinateTool; import es.axios.udig.georeferencing.internal.ui.coordinatepanel.tools.DeletedCoordinateListener; import es.axios.udig.georeferencing.internal.ui.coordinatepanel.tools.MoveCoordinateListener; import es.axios.udig.georeferencing.internal.ui.coordinatepanel.tools.MoveCoordinateTool; import es.axios.udig.ui.commons.message.InfoMessage; import es.axios.udig.ui.commons.message.InfoMessage.Type; import es.axios.udig.ui.commons.util.MapUtil; /** * Composite responsible of managing the mark model coordinates edit operations * with the aid of tools that interact with the map and a table to directly edit * them. * * It's also an observer of the {@link GeoReferencingCommand} and * {@link MarkModel}. * * @author Mauricio Pazos (www.axios.es) * @author Aritz Davila (www.axios.es) * @since 1.0.0 * */ public final class CoordinateTableComposite extends Composite implements Observer, GeoReferencingComposite { private CLabel crsLabel = null; private CLabel mapLabel; private Table coordinatesTable = null; private Composite compositeGridCoord = null; private GeoReferencingCommand cmd = null; private IToolContext toolContext = null; private TableColumn tableColumnX = null; private TableColumn tableColumnY = null; private TableColumn tableColumnID = null; private TableEditor editorX = null; private TableEditor editorY = null; @SuppressWarnings("unused") private Thread uiThread = null; private CapturedCoordinateListener capturedListener = null; private DeletedCoordinateListener deletedListener = null; private MoveCoordinateListener moveListener = null; private MouseSelectionListener mapSelectionListener = null; private MouseSelectionListener imageSelectionListener = null; private AddCoordinateTool coordTool = null; private DeleteCoordinateTool deleteTool = null; private MoveCoordinateTool moveTool = null; private ToolBar mapToolBar = null; private ToolItem itemAdd = null; private ToolItem itemDelete = null; private ToolItem itemMove = null; private ImageRegistry registry = null; private List<MouseSelectionListener> listeners = new LinkedList<MouseSelectionListener>(); private ToolItem itemDeleteAll; /** * Constructor method. * * @param cmd * The georeferencing command. * @param parent * The parent composite. * @param style * The style. */ public CoordinateTableComposite(GeoReferencingCommand cmd, Composite parent, int style) { super(parent, style); assert cmd != null; this.cmd = cmd; createContent(); } private void createContent() { this.registry = createImageRegistry(); this.uiThread = Thread.currentThread(); createListeners(); getTools(); GridLayout gridLayout2 = new GridLayout(); gridLayout2.numColumns = 2; gridLayout2.makeColumnsEqualWidth = true; compositeGridCoord = new Composite(this, SWT.BORDER); compositeGridCoord.setLayout(gridLayout2); createCRSselector(compositeGridCoord); createToolbar(compositeGridCoord); createGrid(compositeGridCoord); } /** * Creates the required listeners, the majority of them are tool listeners. */ private void createListeners() { this.capturedListener = new CapturedCoordinateListener() { public void capturedCoordinate(Coordinate newCoord) { addCoordinateFromMapToTable(newCoord); assert getMainComposite().getMapMarkGraphic() != null; getMainComposite().refreshMapGraphicLayer(); } public void activated(boolean active) { itemAdd.setSelection(active); } }; this.deletedListener = new DeletedCoordinateListener() { public void deletedCoordinate(java.awt.Point point, InputEvent event) { deleteFromTable(point, event); // feedback to show the removed coordinate assert getMainComposite().getMapMarkGraphic() != null; getMainComposite().refreshMapGraphicLayer(); } public void activated(boolean active) { itemDelete.setSelection(active); } }; this.moveListener = new MoveCoordinateListener() { public void MoveCoordinate(java.awt.Point coor, InputEvent event) { moveFromTable(coor, event); // feedback to show the removed coordinate assert getMainComposite().getMapMarkGraphic() != null; getMainComposite().refreshMapGraphicLayer(); } public void activated(boolean active) { itemMove.setSelection(active); } }; this.mapSelectionListener = new MouseSelectionListener() { public void inEvent(MarkModel mark) { selectRow(mark); } public void outEvent(MarkModel mark) { deselectRow(mark); } }; this.imageSelectionListener = new MouseSelectionListener() { public void inEvent(MarkModel mark) { selectRow(mark); } public void outEvent(MarkModel mark) { deselectRow(mark); } }; } /** * Creates the {@link ImageRegistry} that stores the image shown by the * tools. * * @return The imageRegistry. */ private ImageRegistry createImageRegistry() { ImageRegistry registry = new ImageRegistry(this.getDisplay()); String opId = "Delete"; //$NON-NLS-1$ String imgFile = "image/delete.gif"; //$NON-NLS-1$ registry.put(opId, ImageDescriptor.createFromFile(CoordinateTableComposite.class, imgFile)); opId = "Add"; //$NON-NLS-1$ imgFile = "image/add.png"; //$NON-NLS-1$ registry.put(opId, ImageDescriptor.createFromFile(CoordinateTableComposite.class, imgFile)); opId = "Move"; //$NON-NLS-1$ imgFile = "image/movemarker.png"; //$NON-NLS-1$ registry.put(opId, ImageDescriptor.createFromFile(CoordinateTableComposite.class, imgFile)); opId = "DeleteAll"; //$NON-NLS-1$ imgFile = "image/deleteAll.gif"; //$NON-NLS-1$ registry.put(opId, ImageDescriptor.createFromFile(CoordinateTableComposite.class, imgFile)); return registry; } /** * Gets a reference to the tools and add the listeners. */ private void getTools() { Tool tool = ApplicationGIS.getToolManager().findTool(AddCoordinateTool.ID); this.coordTool = (AddCoordinateTool) tool; this.coordTool.addCapturedCoordinateListener(capturedListener); tool = ApplicationGIS.getToolManager().findTool(DeleteCoordinateTool.ID); this.deleteTool = (DeleteCoordinateTool) tool; this.deleteTool.addDeletedCoordinateListener(deletedListener); tool = ApplicationGIS.getToolManager().findTool(MoveCoordinateTool.ID); this.moveTool = (MoveCoordinateTool) tool; this.moveTool.addMoveCoordinateListener(moveListener); } private void createCRSselector(Composite parent) { GridData gridData = new GridData(); gridData.horizontalAlignment = GridData.FILL; gridData.grabExcessHorizontalSpace = true; gridData.grabExcessVerticalSpace = false; gridData.horizontalSpan = 1; gridData.verticalAlignment = GridData.FILL; mapLabel = new CLabel(parent, SWT.NONE); mapLabel.setText(Messages.CoordinateTableComposite_map); mapLabel.setLayoutData(gridData); crsLabel = new CLabel(parent, SWT.NONE); crsLabel.setText("CRS:"); //$NON-NLS-1$ crsLabel.setLayoutData(gridData); } /** * Creates the toolbar that contains the tools that interact with the map. * * @param parent * The parent composite. */ private void createToolbar(Composite parent) { GridData gridData = new GridData(); gridData.horizontalAlignment = GridData.FILL; gridData.grabExcessHorizontalSpace = true; gridData.grabExcessVerticalSpace = false; gridData.horizontalSpan = 2; gridData.verticalAlignment = GridData.FILL; mapToolBar = new ToolBar(parent, SWT.LEFT_TO_RIGHT); final IAction addTool = ApplicationGIS.getToolManager().getToolAction(AddCoordinateTool.ID, AddCoordinateTool.CATEGORY_ID); itemAdd = new ToolItem(mapToolBar, SWT.RADIO); itemAdd.setImage(this.registry.get("Add")); //$NON-NLS-1$ itemAdd.setToolTipText(Messages.CoordinateTableComposite_itemAddTooltip); itemAdd.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { addTool.run(); } }); final IAction deleteTool = ApplicationGIS.getToolManager().getToolAction(DeleteCoordinateTool.ID, DeleteCoordinateTool.CATEGORY_ID); itemDelete = new ToolItem(mapToolBar, SWT.RADIO); itemDelete.setImage(this.registry.get("Delete")); //$NON-NLS-1$ itemDelete.setToolTipText(Messages.CoordinateTableComposite_itemDeleteTooltip); itemDelete.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { deleteTool.run(); } }); final IAction moveTool = ApplicationGIS.getToolManager().getToolAction(MoveCoordinateTool.ID, MoveCoordinateTool.CATEGORY_ID); itemMove = new ToolItem(mapToolBar, SWT.RADIO); itemMove.setImage(this.registry.get("Move")); //$NON-NLS-1$ itemMove.setToolTipText(Messages.CoordinateTableComposite_itemMoveTooltip); itemMove.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { moveTool.run(); } }); itemDeleteAll = new ToolItem(mapToolBar, SWT.PUSH); itemDeleteAll.setImage(this.registry.get("DeleteAll")); //$NON-NLS-1$ itemDeleteAll.setToolTipText(Messages.CoordinateTableComposite_itemDeleteAll_Tooltip); itemDeleteAll.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { deleteAllGCP(); } }); setItemsEnabled(false); setCertainItemsEnabled(false); } private void setItemsEnabled(boolean enabled) { itemAdd.setEnabled(enabled); } private void setCertainItemsEnabled(boolean enabled) { itemDelete.setEnabled(enabled); itemMove.setEnabled(enabled); itemDeleteAll.setEnabled(enabled); if (!enabled) { itemDelete.setSelection(false); itemMove.setSelection(false); itemDeleteAll.setSelection(false); } } private void createGrid(final Composite parent) { GridData gridData = new GridData(); gridData.horizontalAlignment = GridData.FILL; gridData.grabExcessHorizontalSpace = true; gridData.grabExcessVerticalSpace = true; gridData.horizontalSpan = 2; gridData.verticalAlignment = GridData.FILL; coordinatesTable = new Table(parent, SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.HIDE_SELECTION); coordinatesTable.setHeaderVisible(true); coordinatesTable.setLayoutData(gridData); coordinatesTable.setLinesVisible(true); tableColumnID = new TableColumn(coordinatesTable, SWT.NONE); tableColumnID.setWidth(45); tableColumnID.setText("ID"); //$NON-NLS-1$ tableColumnID.setMoveable(true); tableColumnID.setResizable(true); tableColumnX = new TableColumn(coordinatesTable, SWT.NONE); tableColumnX.setText("X"); //$NON-NLS-1$ tableColumnX.setMoveable(true); tableColumnX.setResizable(true); tableColumnY = new TableColumn(coordinatesTable, SWT.NONE); tableColumnY.setText("Y"); //$NON-NLS-1$ tableColumnY.setMoveable(true); tableColumnY.setResizable(true); parent.addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { Rectangle area = parent.getClientArea(); Point size = coordinatesTable.computeSize(SWT.DEFAULT, SWT.DEFAULT); ScrollBar vBar = coordinatesTable.getVerticalBar(); int width = area.width - coordinatesTable.computeTrim(0, 0, 0, 0).width - vBar.getSize().x; if (size.y > area.height + coordinatesTable.getHeaderHeight()) { // Subtract the scrollbar width from the total column width // if a vertical scrollbar will be required Point vBarSize = vBar.getSize(); width -= vBarSize.x; } Point oldSize = coordinatesTable.getSize(); if (oldSize.x > area.width) { // table is getting smaller so make the columns // smaller first and then resize the table to // match the client area width tableColumnX.setWidth(width / 3); tableColumnY.setWidth(width - tableColumnX.getWidth()); coordinatesTable.setSize(area.width, area.height); } else { // table is getting bigger so make the table // bigger first and then make the columns wider // to match the client area width coordinatesTable.setSize(area.width, area.height); tableColumnX.setWidth(width / 3); tableColumnY.setWidth(width - tableColumnX.getWidth()); } } }); editorX = new TableEditor(coordinatesTable); // The editor must have the same size as the cell and must // not be any smaller than 50 pixels. editorX.horizontalAlignment = SWT.LEFT; editorX.grabHorizontal = true; editorX.minimumWidth = 50; editorY = new TableEditor(coordinatesTable); // The editor must have the same size as the cell and must // not be any smaller than 50 pixels. editorY.horizontalAlignment = SWT.LEFT; editorY.grabHorizontal = true; editorY.minimumWidth = 50; coordinatesTable.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // Clean up any previous editor control deleteOldEditors(); // Identify the selected row final TableItem item = (TableItem) e.item; if (item == null) return; // get the mark associated to this row. final MarkModel mark = (MarkModel) item.getData(); createEditorColumnX(mark, item); createEditorColumnY(mark, item); // show feedback using listeners broadcastSelectionInEvent(mark); getMainComposite().refreshMapGraphicLayer(); } }); } /** * Creates the column editor to edit the X coordinate values. * * @param mark * Associated mark model * @param item * Table item. */ private void createEditorColumnX(final MarkModel mark, final TableItem item) { // The control that will be the editor must be a child of the // Table final Text editorColumnX = new Text(coordinatesTable, SWT.NONE); if (mark != null && !(mark.getXCoord().equals(Double.NaN))) { editorColumnX.setText(String.valueOf(mark.getXCoord())); } editorColumnX.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { Text text = (Text) editorX.getEditor(); String newText = text.getText(); if (mark != null) { try { // first, try to parse the text into double Double value = Double.parseDouble(newText); mark.setXCoord(value); cmd.evalPrecondition(); getMainComposite().refreshMapGraphicLayer(); } catch (NumberFormatException ex) { if (newText.equals("")) { //$NON-NLS-1$ mark.setXCoord(Double.NaN); } else { newText = String.valueOf(mark.getXCoord()); } cmd.evalPrecondition(); getMainComposite().refreshMapGraphicLayer(); } } item.setText(1, newText); } }); editorColumnX.addKeyListener(new KeyListener() { public void keyReleased(KeyEvent e) { // not used } public void keyPressed(KeyEvent e) { try { validateCharacter(e); } catch (NumberFormatException ex) { e.doit = false; } } }); editorColumnX.selectAll(); editorColumnX.setFocus(); editorX.setEditor(editorColumnX, item, 1); } /** * Creates the column editor to edit the Y coordinate values. * * @param mark * Associated mark model * @param item * Table item. */ private void createEditorColumnY(final MarkModel mark, final TableItem item) { final Text editorColumnY = new Text(coordinatesTable, SWT.NONE); if (mark != null && !(mark.getYCoord().equals(Double.NaN))) { editorColumnY.setText(String.valueOf(mark.getYCoord())); } editorColumnY.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { Text text = (Text) editorY.getEditor(); String newText = text.getText(); if (mark != null) { try { // first, try to parse the text into double Double value = Double.parseDouble(newText); mark.setYCoord(value); cmd.evalPrecondition(); getMainComposite().refreshMapGraphicLayer(); } catch (NumberFormatException ex) { if (newText.equals("")) { //$NON-NLS-1$ mark.setYCoord(Double.NaN); } else { newText = String.valueOf(mark.getYCoord()); } cmd.evalPrecondition(); getMainComposite().refreshMapGraphicLayer(); } } item.setText(2, newText); } }); editorColumnY.addKeyListener(new KeyListener() { public void keyReleased(KeyEvent e) { // not used } public void keyPressed(KeyEvent e) { try { validateCharacter(e); } catch (NumberFormatException ex) { e.doit = false; } } }); editorY.setEditor(editorColumnY, item, 2); } /** * Delete old editors from the coordinate table. */ private void deleteOldEditors() { Control oldEditorX = editorX.getEditor(); if (oldEditorX != null) oldEditorX.dispose(); Control oldEditorY = editorY.getEditor(); if (oldEditorY != null) oldEditorY.dispose(); } /** * Listen to the changes occurred to the command and to the mark model. */ public void update(Observable obs, Object arg) { if (obs instanceof GeoReferencingCommand) { setCertainItemsEnabled(cmd.canEnableMapTools()); GeoreferencingCommandEventChange cmdEvent = (GeoreferencingCommandEventChange) arg; MarkModel mark = cmdEvent.getMark(); switch (cmdEvent.getEvent()) { case MARK_ADDED: addMarkOnTable(mark); break; case MARK_DELETED: deleteMarkOnTable(mark); break; case ALL_MARKS_DELETED: deleteAllMarksOnTable(); break; default: break; } } else if (obs instanceof MarkModel) { MarkModel mark = (MarkModel) obs; MarkModelChange event = (MarkModelChange) arg; switch (event) { case MODIFY: modifyCoordinateOnTable(mark); break; default: break; } } } /** * Find the row that contains a reference to this mark model and update the * values of that row. * * @param mark * The mark model. */ private void modifyCoordinateOnTable(MarkModel mark) { boolean selection = false; TableItem[] selectedItems = coordinatesTable.getSelection(); if (selectedItems.length > 0) { selection = true; } // find the row. TableItem[] items = coordinatesTable.getItems(); for (TableItem item : items) { MarkModel compareMark = (MarkModel) item.getData(); if (mark.equals(compareMark)) { Coordinate newCoord = new Coordinate(mark.getXCoord(), mark.getYCoord()); if (selection && selectedItems[0].equals(item)) { // the selected item is the one to update createEditorsAndSetText(mark, item, newCoord); } setRowData(item, mark, newCoord); } } } /** * Creates the table editors and set the current value. * * @param mark * MarkModel model. * @param item * Table item. * @param newCoord * Coordinate with the values. */ private void createEditorsAndSetText(MarkModel mark, TableItem item, Coordinate newCoord) { deleteOldEditors(); createEditorColumnX(mark, item); createEditorColumnY(mark, item); Text textX = (Text) editorX.getEditor(); Text textY = (Text) editorY.getEditor(); if (!(Double.isNaN(newCoord.x))) { textX.setText(String.valueOf(newCoord.x)); } if (!(Double.isNaN(newCoord.y))) { textY.setText(String.valueOf(newCoord.y)); } } /** * <p> * Adds a mark to the table. * * Creates a {@link MarkMapPresenterImp} and associates it with the * {@link MapMarksGraphics}. * </p> * * @param mark * Mark model. */ private void addMarkOnTable(MarkModel mark) { final TableItem tableItem = new TableItem(coordinatesTable, SWT.NONE); // set the mark data to this entire row. tableItem.setData(mark); tableItem.setText(0, String.valueOf(mark.getID())); if (!mark.getXCoord().equals(Double.NaN)) { tableItem.setText(1, String.valueOf(mark.getXCoord())); } if (!mark.getYCoord().equals(Double.NaN)) { tableItem.setText(2, String.valueOf(mark.getYCoord())); } // if a previous row is selected, select the new created row. updateRowSelection(tableItem, mark); assert getMainComposite().getMapMarkGraphic() != null; // create the MarkMapGraphics associated to this mark MarkMapPresenter markPresenter = new MarkMapPresenterImp(mark); getMainComposite().getMapMarkGraphic().addMarkMapPresenter(markPresenter); setItemsEnabled(true); mark.addObserver(this); } /** * Given the next scenario: * * <pre> * - New row added * - There was a previous row selected. * </pre> * * Update the selected row so it'll select the newly created row. * * @param tableItem * Table item. * @param mark * Mark model. */ private void updateRowSelection(TableItem addedItem, MarkModel mark) { TableItem[] selection = coordinatesTable.getSelection(); if (selection.length > 0) { // get the new item coordinatesTable.setSelection(addedItem); deleteOldEditors(); createEditorColumnX(mark, addedItem); createEditorColumnY(mark, addedItem); } } /** * Adds a coordinate to the table. * * There must be 1 empty row. If there is a selected row and also is empty, * then the coordinate will be added there. If there isn't any selected row, * the coordinate will be added in the first empty row. If there isn't any * empty rows, the coordinate won't be added. * * * @param newCoord * Coordinate to be added. */ private void addCoordinateFromMapToTable(Coordinate newCoord) { TableItem[] selection = coordinatesTable.getSelection(); if (selection.length > 0) { // selected item // get the row and add the coordinate to that row. TableItem item = selection[0]; addCoordinateOnTable(item, newCoord, true); } else {// non selected item // get the first empty row and add the coordinate to that row. boolean added = false; TableItem[] items = coordinatesTable.getItems(); for (TableItem item : items) { added = addCoordinateOnTable(item, newCoord, false); // if the coordinate was added, return. if (added) return; } // if the code reach this point, the coordinate wasn't added, show // an advertise message. getMainComposite() .setMessage(new InfoMessage(Messages.CoordinateTableComposite_cant_add_gcp, Type.WARNING)); } } /** * Finds the {@link MainComposite} and returns it. * * @return The main composite. */ private MainComposite getMainComposite() { if (isDisposed()) { return null; } Composite parent = getParent(); for (;;) { if (parent instanceof MainComposite) { return (MainComposite) parent; } else { parent = parent.getParent(); } } } /** * Validate if the given character is a valid integer. * * @param e * @throws NumberFormatException * When the given character isn't an Integer. */ private void validateCharacter(KeyEvent e) throws NumberFormatException { if (e.character == '.' || e.keyCode == SWT.DEL || e.keyCode == SWT.BS || e.keyCode == SWT.END || e.keyCode == SWT.HOME || e.keyCode == 16777219 || e.keyCode == 16777220 || e.character == '-' || e.character == '+') { return; } Integer.parseInt(String.valueOf(e.character)); } /** * Delete this mark on the table and refresh the layer that contains the * mapGraphic so the changed are shown. * * @param mark * Mark model to be deleted. */ private void deleteMarkOnTable(MarkModel mark) { int index = getMarkIndexWithinTheTable(mark); deleteOldEditors(); coordinatesTable.remove(index); getMainComposite().refreshMapGraphicLayer(); mark.deleteObserver(this); } /** * Find the index of this mark model searching all the table items. * * @param mark * The mark model. * @return The index. */ private int getMarkIndexWithinTheTable(MarkModel mark) { int index = -1; // find this mark on the table TableItem[] items = coordinatesTable.getItems(); for (TableItem item : items) { index++; MarkModel itemMark = (MarkModel) item.getData(); if (mark.equals(itemMark)) { break; } } assert index != -1 : "index can't be null, it must have found the given mark."; //$NON-NLS-1$ return index; } /** * Delete all the marks from the coordinate table. */ private void deleteAllMarksOnTable() { deleteOldEditors(); TableItem[] items = coordinatesTable.getItems(); coordinatesTable.remove(0, items.length - 1); assert coordinatesTable.getItems().length == 0; getMainComposite().getMapMarkGraphic().clear(); } /** * Add a coordinate into table when mark associated to this table item * doesn't have any coordinate value stored. * * @param item * Table item * @param newCoord * Coordinate to be added. * @return True when the coordinate was added into the table. */ private boolean addCoordinateOnTable(TableItem item, Coordinate newCoord, boolean existSelection) { MarkModel mark = (MarkModel) item.getData(); if (existSelection) { createEditorsAndSetText(mark, item, newCoord); setRowData(item, mark, newCoord); } else if (mark.getXCoord().equals(Double.NaN) && mark.getYCoord().equals(Double.NaN)) { // if // marks // are // empty. setRowData(item, mark, newCoord); return true; } return false; } /** * Set the data of the given coordinate in the mark model and in the table. * * @param item * Table item. * @param mark * MarkModel model. * @param newCoord * The coordinate containing the data. */ private void setRowData(TableItem item, MarkModel mark, Coordinate newCoord) { if (!(Double.isNaN(newCoord.x))) { item.setText(1, String.valueOf(newCoord.x)); } else { item.setText(1, ""); //$NON-NLS-1$ } if (!(Double.isNaN(newCoord.y))) { item.setText(2, String.valueOf(newCoord.y)); } else { item.setText(2, ""); //$NON-NLS-1$ } mark.setXCoord(newCoord.x); mark.setYCoord(newCoord.y); // evaluate preconditions this.cmd.evalPrecondition(); } /** * The first time, adds the listeners. */ public void setContext(IToolContext newContext) { if (this.toolContext == null) { // add the listener the first time. getMainComposite().getMapMarkGraphic().addMouseSelectionListener(mapSelectionListener); getMainComposite().addMouseSelectionListenerToImgComposite(imageSelectionListener); } this.toolContext = newContext; if (toolContext != null) { // display the map IMap map = toolContext.getMap(); mapLabel.setText("Map: " + map.getName()); //$NON-NLS-1$ // display the CRS. CoordinateReferenceSystem crs = getCurrentMapCrs(map); crsLabel.setText("CRS: " + crs.getName().toString()); //$NON-NLS-1$ } } /** * @param map * @return the current map's CRS or null if current map is null */ private CoordinateReferenceSystem getCurrentMapCrs(IMap map) { CoordinateReferenceSystem crs = (map != null) ? MapUtil.getCRS(map) : null; return crs; } /** * Remove all the listeners of the tools and de-activates them. * * @param mainComposite * The main composite. */ public void close(MainComposite mainComposite) { // remove the listener this.coordTool.removeCapturedCoordinateListener(this.capturedListener); this.deleteTool.removeDeletedCoordinateListener(this.deletedListener); this.moveTool.removeMoveCoordinateListener(this.moveListener); this.coordTool.setActive(false); this.deleteTool.setActive(false); this.moveTool.setActive(false); if (this.toolContext != null) {// & !isDisposed()) { // delete the listener mainComposite.getMapMarkGraphic().deleteMouseSelectionListener(mapSelectionListener); mainComposite.deleteMouseSelectionListenerToImgComposite(imageSelectionListener); } } @Override public void setEnabled(boolean enabled) { this.coordinatesTable.setEnabled(enabled); if (this.editorX.getEditor() != null && !this.editorX.getEditor().isDisposed()) { this.editorX.getEditor().setEnabled(enabled); } if (this.editorY.getEditor() != null && !this.editorY.getEditor().isDisposed()) { this.editorY.getEditor().setEnabled(enabled); } setItemsEnabled(enabled); setCertainItemsEnabled(enabled); super.setEnabled(enabled); } /** * <p> * When a mouse_down event occur, gets all the map presenters and search if * any of these presenters are affected by the event. If any of the * presenter returns true, this mark coordinate data will be deleted from * the table and from the mark model. * * If the event is not a mouse_down, delegates the event to the * {@link MapMarksGraphics}. * </p> * * @param point * Map point where it was clicked. * @param event * Input event. */ private void deleteFromTable(java.awt.Point point, InputEvent event) { if (InputEvent.MOUSE_DOWN.equals(event)) { // get the presenters Map<String, MarkMapPresenter> presenters = getMainComposite().getMapMarkGraphic().getPresenters(); // iterate the presenters and see if the point belongs to any mark MarkModel mark = null; Set<Entry<String, MarkMapPresenter>> entrySet = presenters.entrySet(); Iterator<Entry<String, MarkMapPresenter>> iter = entrySet.iterator(); while (iter.hasNext()) { Entry<String, MarkMapPresenter> entry = iter.next(); MarkMapPresenter mapPresenter = entry.getValue(); if (mapPresenter.eventHandler(InputEvent.DELETE, point.x, point.y)) { mark = mapPresenter.getMarkModel(); break; } } if (mark != null) { deleteOldEditors(); int index = getMarkIndexWithinTheTable(mark); TableItem item = coordinatesTable.getItem(index); item.setText(1, ""); //$NON-NLS-1$ item.setText(2, ""); //$NON-NLS-1$ mark.setXCoord(Double.NaN); mark.setYCoord(Double.NaN); this.cmd.evalPrecondition(); getMainComposite().refreshMapGraphicLayer(); } } else { getMainComposite().getMapMarkGraphic().eventhandler(event, point); } } /** * Delegate the move event to the {@link MapMarksGraphics}. * * @param point * Map point where it was clicked. * @param event * Input event. */ private void moveFromTable(java.awt.Point point, InputEvent event) { // the mapMarkGraphics will be the responsible to handle these // behaviours getMainComposite().getMapMarkGraphic().eventhandler(event, point); } /** * Selects the row corresponding to the given mark. * * @param mark * MarkModel */ private void selectRow(MarkModel mark) { deleteOldEditors(); int index = getMarkIndexWithinTheTable(mark); assert index >= 0; coordinatesTable.setSelection(index); createEditorColumnX(mark, coordinatesTable.getSelection()[0]); createEditorColumnY(mark, coordinatesTable.getSelection()[0]); } /** * If a row is selected and it owns the given mark model, it'll deselect it. * * @param mark * The mark model. */ private void deselectRow(MarkModel mark) { int index = getMarkIndexWithinTheTable(mark); int selection = coordinatesTable.getSelectionIndex(); if (index == selection) { coordinatesTable.deselect(selection); deleteOldEditors(); } } /** * Adds a {@link MouseSelectionListener}. * * @param listener * The listener. */ public void addMouseSelectionListener(MouseSelectionListener listener) { listeners.add(listener); } /** * Deletes a {@link MouseSelectionListener}. * * @param listener * The listener. */ public void deleteMouseSelectionListener(MouseSelectionListener listener) { listeners.remove(listener); } /** * Broadcast to all its listeners that the given mark has been selected in * the coordinate table. * * @param mark * The mark model */ private void broadcastSelectionInEvent(MarkModel mark) { for (MouseSelectionListener listener : listeners) { listener.inEvent(mark); } } private void deleteAllGCP() { Coordinate emptyCoord = new Coordinate(Double.NaN, Double.NaN); TableItem[] items = this.coordinatesTable.getItems(); for (TableItem item : items) { MarkModel itemMark = (MarkModel) item.getData(); itemMark.updateCoordinatePosition(emptyCoord); } getMainComposite().refreshMapGraphicLayer(); } }