package cytoscape.editor.cyAnnotator; //Also contains viewport, mouse, mouseMotion and some other listeners import cytoscape.editor.cyAnnotator.Annotations.*; import cytoscape.editor.cyAnnotator.createAnnotation.*; import java.awt.event.*; import javax.swing.*; import java.awt.*; import java.awt.dnd.*; import java.awt.datatransfer.*; import cytoscape.Cytoscape; import cytoscape.ding.DingNetworkView; import ding.view.*; import java.util.ArrayList; public class CyAnnotator{ private MyViewportChangeListener myViewportChangeListener=null; private static boolean USE_FONT_RESIZE=true, DRAG_VAL=false, annotationEnlarge=false, drawShape=false; private ArrayList selectedAnnotations=new ArrayList(); private double prevZoom=1; private ShapeAnnotation newShape=null, createShape=null; public CyAnnotator() { initListeners(); } public void initListeners(){ ((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS).addMouseListener(new ForegroundMouseListener()); ((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS).addMouseMotionListener(new ForegroundMouseMotionListener()); ((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS).addKeyListener(new ForegroundKeyListener()); ((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS).setFocusable(true); //Set up the foregroundCanvas as a dropTarget, so that we can drag and drop JPanels, created Annotations onto it. //We also set it up as a DragSource, so that we can drag created Annotations addDropTarget((ArbitraryGraphicsCanvas)(((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS))); addDragSource((ArbitraryGraphicsCanvas)(((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS))); if(USE_FONT_RESIZE){ //The created annotations resize (Their font changes), if we zoom in and out ((ArbitraryGraphicsCanvas)(((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS))).addMouseWheelListener(new MyMouseWheelListener()); //We also setup this class as a ViewportChangeListener to the current networkView myViewportChangeListener=new MyViewportChangeListener(); ((DingNetworkView)Cytoscape.getCurrentNetworkView()).addViewportChangeListener(myViewportChangeListener); } } class MyViewportChangeListener implements ViewportChangeListener{ public void viewportChanged(int x, int y, double width, double height, double newZoom) { //We adjust the font size of all the created annotations if the if there are changes in viewport Component[] annotations=((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS).getComponents(); for(int i=0;i<annotations.length;i++){ if(annotations[i] instanceof TextAnnotation) ((TextAnnotation)annotations[i]).adjustFont(newZoom); } Cytoscape.getDesktop().getNetworkViewManager().getInternalFrameComponent(Cytoscape.getCurrentNetworkView()).repaint(); } } public void startDrawShape(ShapeAnnotation createShape, int x, int y){ drawShape=true; this.createShape=createShape; //createShape will have all the properties associated with the shape to be drawn //Create a shapeAnnotattion based on these properties and add it to foregroundCanvas newShape= new ShapeAnnotation(x, y, createShape.getShapeType(), createShape.getFillColor(), createShape.getEdgeColor(), createShape.getEdgeThickness()); ((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS).add(newShape); } public void addDragSource(ArbitraryGraphicsCanvas foregroundCanvas){ DragSourceComponent source=new DragSourceComponent(foregroundCanvas); } class DragSourceComponent extends DragSourceAdapter implements DragGestureListener{ //Add the foregroundCanvas as DraggableComponent DragSource dragSource; DragSourceComponent(ArbitraryGraphicsCanvas foregroundCanvas){ dragSource = new DragSource(); dragSource.createDefaultDragGestureRecognizer( foregroundCanvas, DnDConstants.ACTION_COPY_OR_MOVE, this); } public void dragGestureRecognized(DragGestureEvent dge) { Component annotation=((ArbitraryGraphicsCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS)).getComponentAt((int)(dge.getDragOrigin().getX()), (int)(dge.getDragOrigin().getY())); //Add the component number of the annotation being dragged in the form of string to transfer information if(annotation!=null && (annotation instanceof TextAnnotation)){ Transferable t = new StringSelection(new Integer(((TextAnnotation)annotation).getComponentNumber()).toString()); dragSource.startDrag (dge, DragSource.DefaultCopyDrop, t, this); } } } public void addDropTarget(ArbitraryGraphicsCanvas foregroundCanvas){ DropTargetComponent target=new DropTargetComponent(foregroundCanvas); } public class DropTargetComponent implements DropTargetListener { //Add the foregroundCanvas as a drop Target public DropTargetComponent(ArbitraryGraphicsCanvas foregroundCanvas) { new DropTarget(foregroundCanvas, this); } public void dragEnter(DropTargetDragEvent evt){} public void dragOver(DropTargetDragEvent evt){ try { Transferable t = evt.getTransferable(); if (t.isDataFlavorSupported(DataFlavor.stringFlavor)) { String s = (String)t.getTransferData(DataFlavor.stringFlavor); //Get hold of the transfer information and complete the drop //Based on that information popup appropriate JFrames to create those Annotatons Component annotation=((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS).getComponent(Integer.parseInt(s)); if(annotation instanceof TextAnnotation) { if(!((TextAnnotation)annotation).getDrawArrow()){ //The drop has been done to move an annotation to a new location annotation.setLocation((int)evt.getLocation().getX(),(int)evt.getLocation().getY()); //This will modify the initial location of this annotation stored in an array in foregroundCanvas //Very important. Without it you won't be able to handle change in viewports ((ArbitraryGraphicsCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS)).modifyComponentLocation(annotation.getX(), annotation.getY(), ((TextAnnotation)annotation).getComponentNumber()); } } //Repaint the whole network Cytoscape.getDesktop().getNetworkViewManager().getInternalFrameComponent(Cytoscape.getCurrentNetworkView()).repaint(); } } catch (Exception e) { e.printStackTrace(); } } public void dragExit(DropTargetEvent evt){} public void dropActionChanged(DropTargetDragEvent evt){} public void drop(DropTargetDropEvent evt) { try { Transferable t = evt.getTransferable(); if (t.isDataFlavorSupported(DataFlavor.stringFlavor)) { evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); String s = (String)t.getTransferData(DataFlavor.stringFlavor); evt.getDropTargetContext().dropComplete(true); //Get hold of the transfer information and complete the drop //Based on that information popup appropriate JFrames to create those Annotatons Component annotation=((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS).getComponent(Integer.parseInt(s)); if(annotation instanceof TextAnnotation) { if(((TextAnnotation)annotation).getDrawArrow()){ //The drop has been done to create a new Arrow from an Annotation ((TextAnnotation)annotation).setDrawArrow(false); ((TextAnnotation)annotation).setArrowPoints((int)evt.getLocation().getX(),(int)evt.getLocation().getY()); ((TextAnnotation)annotation).setArrowDrawn(true); } else{ //The drop has been done to move an annotation to a new location annotation.setLocation((int)evt.getLocation().getX(),(int)evt.getLocation().getY()); //This will modify the initial location of this annotation stored in an array in foregroundCanvas //Very important. Without it you won't be able to handle change in viewports ((ArbitraryGraphicsCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS)).modifyComponentLocation(annotation.getX(), annotation.getY(), ((TextAnnotation)annotation).getComponentNumber()); } } //Repaint the whole network Cytoscape.getDesktop().getNetworkViewManager().getInternalFrameComponent(Cytoscape.getCurrentNetworkView()).repaint(); } else{ ((InnerCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.NETWORK_CANVAS)).getDropTarget().drop(evt); } } catch (Exception e) { e.printStackTrace(); evt.rejectDrop(); } } } class MyMouseWheelListener implements MouseWheelListener{ //To handle zooming in and out public void mouseWheelMoved(MouseWheelEvent e) { int notches = e.getWheelRotation(); double factor = 1.0; // scroll up, zoom in if (notches < 0) factor = 1.1; else factor = 0.9; if(annotationEnlarge){ //If some annotations are selected for(int i=0;i<selectedAnnotations.size();i++) ((TextAnnotation)selectedAnnotations.get(i)).adjustSpecificFont( prevZoom * factor ); //In that case only increase the size (Change font in some cases) for those specific annotations prevZoom*=factor; } else{ ((InnerCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas()).mouseWheelMoved(e); } Cytoscape.getDesktop().getNetworkViewManager().getInternalFrameComponent(Cytoscape.getCurrentNetworkView()).repaint(); } } //Returns a boolean value, whether this is a Mac Platform or not private boolean isMacPlatform() { String MAC_OS_ID = "mac"; String os = System.getProperty("os.name"); return os.regionMatches(true, 0, MAC_OS_ID, 0, MAC_OS_ID.length()); } class ForegroundMouseListener implements MouseListener{ public ForegroundMouseListener() { } public void mousePressed(MouseEvent e) { Component newOne=((ArbitraryGraphicsCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS)).getComponentAt(e.getX(), e.getY()); if(newOne!=null && newOne instanceof TextAnnotation){ //We might drag this annotation DRAG_VAL=true; //We have right clicked on the Annotation, show a popup if( (e.getButton() == MouseEvent.BUTTON3) || ( isMacPlatform() && e.isControlDown()) ) ((TextAnnotation)newOne).showChangePopup(e); } else{ //Let the InnerCanvas handle this event ((InnerCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas()).mousePressed(e); } } public void mouseReleased(MouseEvent e) { //We might have finished dragging this Annotation DRAG_VAL=false; //Let the InnerCanvas handle this event ((InnerCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas()).mouseReleased(e); } public void mouseClicked(MouseEvent e) { Component newOne=((ArbitraryGraphicsCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS)).getComponentAt(e.getX(), e.getY()); if(newOne instanceof TextAnnotation) { if(e.getClickCount()==2 && newOne!=null && !((TextAnnotation)newOne).pointOnArrow){ //We have doubled clicked on an Annotation annotationEnlarge=true; //Add this Annotation to the list of selected Annotations selectedAnnotations.add(newOne); //This preVZoom value will help in resizing the selected Annotations prevZoom=((InnerCanvas)(((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.NETWORK_CANVAS))).getScaleFactor(); ((TextAnnotation)newOne).setTempZoom(prevZoom); ((TextAnnotation)newOne).setSelected(true); //We request focus in this window, so that we can move these selected Annotations around using arrow keys ((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS).requestFocusInWindow(); //Repaint the whole network. The selected annotations will have a yellow outline now Cytoscape.getDesktop().getNetworkViewManager().getInternalFrameComponent(Cytoscape.getCurrentNetworkView()).repaint(); } } else if(drawShape){ drawShape=false; //We have finished drawing a shapeAnnotation //We set the otherCorner of that Annotation newShape.setOtherCorner(e.getX(), e.getY()); newShape.adjustCorners(); Cytoscape.getDesktop().getNetworkViewManager().getInternalFrameComponent(Cytoscape.getCurrentNetworkView()).repaint(); } else if(newOne==null) { //Handle the case where we have clicked on a node //We have clicked somewhere else on the network, de-select all the selected Annotations annotationEnlarge=false; if(!selectedAnnotations.isEmpty()){ for(int i=0;i<selectedAnnotations.size();i++) ((TextAnnotation)selectedAnnotations.get(i)).setSelected(false); selectedAnnotations.clear(); } Cytoscape.getDesktop().getNetworkViewManager().getInternalFrameComponent(Cytoscape.getCurrentNetworkView()).repaint(); } else{ //Let the InnerCanvas handle this event ((InnerCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas()).mouseClicked(e); } } public void mouseEntered(MouseEvent e) { ((InnerCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas()).mouseEntered(e); } public void mouseExited(MouseEvent e) { ((InnerCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas()).mouseExited(e); } } class ForegroundMouseMotionListener implements MouseMotionListener{ public ForegroundMouseMotionListener() { } public void mouseDragged(MouseEvent e) { //If we are not dragging an Annotation then let the InnerCanvas handle this event if(!DRAG_VAL) ((InnerCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas()).mouseDragged(e); } public void mouseMoved(MouseEvent e) { if(drawShape){ //We are drawing a shape newShape.setOtherCorner(e.getX(), e.getY()); Cytoscape.getDesktop().getNetworkViewManager().getInternalFrameComponent(Cytoscape.getCurrentNetworkView()).repaint(); } else ((InnerCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas()).mouseMoved(e); } } class ForegroundKeyListener implements KeyListener{ public void keyPressed(KeyEvent e) { int code = e.getKeyCode(); if(annotationEnlarge && ( (code == KeyEvent.VK_UP) || (code == KeyEvent.VK_DOWN) || (code == KeyEvent.VK_LEFT)|| (code == KeyEvent.VK_RIGHT) ) ) { //Some annotations have been double clicked and selected int move=2; for(int i=0;i<selectedAnnotations.size();i++){ TextAnnotation temp=((TextAnnotation)selectedAnnotations.get(i)); int x=temp.getX(), y=temp.getY(); if (code == KeyEvent.VK_UP) y-=move; else if (code == KeyEvent.VK_DOWN) y+=move; else if (code == KeyEvent.VK_LEFT) x-=move; else if (code == KeyEvent.VK_RIGHT) x+=move; //Adjust the locations of the selected annotations temp.setLocation(x,y); ((ArbitraryGraphicsCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas(DGraphView.Canvas.FOREGROUND_CANVAS)).modifyComponentLocation(temp.getX(), temp.getY(), temp.getComponentNumber()); } Cytoscape.getDesktop().getNetworkViewManager().getInternalFrameComponent(Cytoscape.getCurrentNetworkView()).repaint(); } ((InnerCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas()).keyPressed(e); } public void keyReleased(KeyEvent e) { ((InnerCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas()).keyReleased(e); } public void keyTyped(KeyEvent e) { ((InnerCanvas)((DingNetworkView)Cytoscape.getCurrentNetworkView()).getCanvas()).keyTyped(e); } } }