package com.c2kernel.graph.controller; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import com.c2kernel.graph.model.GraphModelManager; import com.c2kernel.graph.model.GraphPoint; import com.c2kernel.graph.model.Vertex; import com.c2kernel.graph.view.EditorModeListener; import com.c2kernel.graph.view.EditorToolBar; public class EdgeConstructionController extends MouseAdapter implements MouseMotionListener, EditorModeListener { private GraphModelManager mGraphModelManager = null; private EditorToolBar mEditorToolBar = null; /**********/ /* States */ /**********/ private final Integer kOtherMode = new Integer(0); private final Integer kWaitOrigin = new Integer(1); private final Integer kWaitTerminus = new Integer(2); /**********/ /* Events */ /**********/ private final int kEdgeEntered = 0; private final int kOtherEntered = 1; private final int kPressOnVertex = 2; private final int kDrag = 3; private final int kReleaseOnTerminus = 4; private final int kReleaseOnNothing = 5; /***********/ /* Actions */ /***********/ private interface Action { public void doIt(Object data); } private Action mSetOriginVertex = new Action() { public void doIt(Object data) { if(mGraphModelManager != null) { mGraphModelManager.getModel().setNewEdgeOriginVertex((Vertex)data); } } }; private Action mSetEndPoint = new Action() { public void doIt(Object data) { if(mGraphModelManager != null) { mGraphModelManager.getModel().setNewEdgeEndPoint((Point)data); } } }; private Action mClearEdge = new Action() { public void doIt(Object data) { if(mGraphModelManager != null) { mGraphModelManager.getModel().setNewEdgeOriginVertex(null); mGraphModelManager.getModel().setNewEdgeEndPoint(null); } } }; private Action mCreateEdge = new Action() { public void doIt(Object data) { if((mGraphModelManager != null) && (mEditorToolBar != null) && mGraphModelManager.isEditable()) { mGraphModelManager.getModel().createDirectedEdge ( mGraphModelManager.getModel().getNewEdgeOriginVertex(), (Vertex)data, mEditorToolBar.getSelectedEdgeType() ); mGraphModelManager.getModel().setNewEdgeOriginVertex(null); mGraphModelManager.getModel().setNewEdgeEndPoint(null); } } }; /***********************************/ /* Finite State Transition Network */ /***********************************/ private Object[][][] mFSTN = {// OtherMode WaitOrigin WaitTerminus /* EdgeEntered */ {{null, kWaitOrigin}, null , null }, /* OtherEntered */ { null , {null , kOtherMode} , null }, /* PressOnVertex */ { null , {mSetOriginVertex, kWaitTerminus}, null }, /* Drag */ { null , null , {mSetEndPoint, null} }, /* ReleaseOnTerminus */ { null , null , {mCreateEdge , kWaitOrigin}}, /* ReleaseOnNothing */ { null , null , {mClearEdge , kWaitOrigin}} }; /*****************/ /* Current state */ /*****************/ private Integer mState = kOtherMode; /**************************/ /* Event processing logic */ /**************************/ private void processEvent(int event, Object data) { Object[] transition = mFSTN[event][mState.intValue()]; Action action = null; Integer nextState = null; if(transition != null) { action = (Action)transition[0]; nextState = (Integer)transition[1]; if(action != null) { action.doIt(data); } if(nextState != null) { mState = nextState; } } } /********************/ /* Public interface */ /********************/ public void setGraphModelManager(GraphModelManager graphModelManager) { mGraphModelManager = graphModelManager; } public void setEditorToolBar(EditorToolBar editorToolBar) { mEditorToolBar = editorToolBar; mEditorToolBar.addEditorModeListener(this); } public void editorModeChanged(String idOfNewMode) { if(idOfNewMode.equals("Edge")) { processEvent(kEdgeEntered, null); } else { processEvent(kOtherEntered, null); } } public void mousePressed(MouseEvent me) { Vertex vertex = null; Point mousePoint = null; if(mGraphModelManager != null) { // Determine if there is a vertex under the mouse cursor mousePoint = me.getPoint(); vertex = mGraphModelManager.getModel().getVertex(new GraphPoint(mousePoint.x, mousePoint.y)); // If the mouse has been pressed on a vertex if(vertex != null) { processEvent(kPressOnVertex, vertex); } } } public void mouseReleased(MouseEvent me) { Vertex vertex = null; Point mousePoint = null; if(mGraphModelManager != null) { // Determine if there is a vertex under the mouse cursor mousePoint = me.getPoint(); vertex = mGraphModelManager.getModel().getVertex(new GraphPoint(mousePoint.x, mousePoint.y)); // If the mouse has been released on a vertex which is not the origin vertex if((vertex != null) && (vertex != mGraphModelManager.getModel().getNewEdgeOriginVertex())) { processEvent(kReleaseOnTerminus, vertex); } else { processEvent(kReleaseOnNothing, null); } } } public void mouseExited(MouseEvent me) { } public void mouseDragged(MouseEvent me) { processEvent(kDrag, me.getPoint()); } public void mouseMoved(MouseEvent me) { } }