package com.horstmann.violet.workspace.editorpart.behavior; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import com.horstmann.violet.product.diagram.abstracts.IGraph; import com.horstmann.violet.product.diagram.abstracts.edge.IEdge; import com.horstmann.violet.product.diagram.abstracts.node.INode; import com.horstmann.violet.workspace.editorpart.IEditorPart; import com.horstmann.violet.workspace.editorpart.IEditorPartBehaviorManager; import com.horstmann.violet.workspace.editorpart.IEditorPartSelectionHandler; /** * Allows to select the next or the previous element (node_old or edge) by specifying a distance with the current one * * @author Alexandre de Pellegrin * */ public class SelectByDistanceBehavior extends AbstractEditorPartBehavior { public SelectByDistanceBehavior(IEditorPart editorPart) { this.editorPart = editorPart; this.graph = editorPart.getGraph(); this.selectionHandler = editorPart.getSelectionHandler(); this.behaviorManager = editorPart.getBehaviorManager(); } /** * Selects another graph element. * * @param distanceFormCurrentElement distance from the currently selected element. For example : -1 for the previous element and * +1 for the next one. */ public void selectAnotherGraphElement(int distanceFromCurrentElement) { ArrayList<Object> selectables = new ArrayList<Object>(); selectables.addAll(graph.getAllNodes()); selectables.addAll(graph.getAllEdges()); if (selectables.size() == 0) return; java.util.Collections.sort(selectables, new java.util.Comparator<Object>() { public int compare(Object obj1, Object obj2) { double x1; double y1; if (obj1 instanceof INode) { Rectangle2D bounds = ((INode) obj1).getBounds(); x1 = bounds.getX(); y1 = bounds.getY(); } else { Point2D start = ((IEdge) obj1).getConnectionPoints().getP1(); x1 = start.getX(); y1 = start.getY(); } double x2; double y2; if (obj2 instanceof INode) { Rectangle2D bounds = ((INode) obj2).getBounds(); x2 = bounds.getX(); y2 = bounds.getY(); } else { Point2D start = ((IEdge) obj2).getConnectionPoints().getP1(); x2 = start.getX(); y2 = start.getY(); } if (y1 < y2) return -1; if (y1 > y2) return 1; if (x1 < x2) return -1; if (x1 > x2) return 1; return 0; } }); int index; Object lastSelected = null; if (selectionHandler.isNodeSelectedAtLeast()) { lastSelected = selectionHandler.getLastSelectedNode(); } if (selectionHandler.isEdgeSelectedAtLeast()) { lastSelected = selectionHandler.getLastSelectedEdge(); } if (lastSelected == null) index = 0; else index = selectables.indexOf(lastSelected) + distanceFromCurrentElement; while (index < 0) index += selectables.size(); index %= selectables.size(); Object toSelect = selectables.get(index); if (toSelect instanceof INode) { selectionHandler.setSelectedElement((INode) toSelect); behaviorManager.fireOnNodeSelected((INode) toSelect); } if (toSelect instanceof IEdge) { selectionHandler.setSelectedElement((IEdge) toSelect); behaviorManager.fireOnEdgeSelected((IEdge) toSelect); } this.editorPart.getSwingComponent().invalidate(); } private IEditorPart editorPart; private IGraph graph; private IEditorPartSelectionHandler selectionHandler; private IEditorPartBehaviorManager behaviorManager; }