/*--------------------------------------------------------------------------- -- JAWAA 2.0 -- Copyright information: Susan H. Rodger, Pretesh Patel, Diana Jackson, Ayonike Akingbade Computer Science Department Duke University August 2002 Supported by National Science Foundation DUE-9752583. Copyright (c) 2002 All rights reserved. Redistribution and use in source and binary forms are permitted provided that the above copyright notice and this paragraph are duplicated in all such forms and that any documentation, advertising materials, and other materials related to such distribution and use acknowledge that the software was developed by the author. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ---------------------------------------------------------------------------*/ /*------------------------------------------------------------------------------- File: JawaaGraphNode.java Package: JAWAA Version 2.0 Author: Pretesh Patel, Diana Jackson, Ayonike Akingbade Date: August 2002 Description of Contents: This object represents a graph node. It contains accessor and setter functions. The object also knows how to draw itself. ---------------------------------------------------------------------------------*/ package jawaa.structure; import java.awt.*; import jawaa.object.*; import java.util.Vector; import jawaa.util.JawaaHash; import jawaa.extras.arrow.*; import jawaa.extras.marker.*; import jawaa.extras.*; import jawaa.util.*; public class JawaaGraphNode extends JawaaNode implements ArrowMonger, Markable { public JawaaGraphNode(String[] s) { super(s); myPointers = new Vector(); myArrows = new Vector(); } public JawaaGraphNode(String name, Color foreground, Color background, Color textColor, String[] s, int x, int y, int width, int height) { super(name, foreground, background, textColor, s, x, y, width, height); myPointers = new Vector(); myArrowColor = foreground; myArrows = new Vector(); } public JawaaGraphNode(String name, Color foreground, Color background, Color textColor, String[] s, int x, int y, int width, int height, JawaaGraphNode n) { super(name, foreground, background, textColor, s, x, y, width, height); myPointers = new Vector(); myArrowColor = foreground; myArrows = new Vector(); buildArrow(n); } public JawaaGraphNode(String name, Color foreground, Color background, Color textColor, JawaaText[] t, Point p, int width, int height, JawaaShape out) { super(name, foreground, background, textColor, t, p, width, height,out); myPointers = new Vector(); myArrowColor = foreground; myArrows = new Vector(); } public void buildArrow(JawaaGraphNode n) { SmartArrow arrow = new SmartArrow(this, n, myColor); n.addPointer(arrow); myArrowColor = myColor; myArrows.addElement(arrow); } public void offsetLocation(int x, int y) { Point p = new Point(myLocation.x+x, myLocation.y+y); super.offsetLocation(x,y); fireActionPerformed(p); } public void setLocation(int x, int y) { Point p = new Point(myLocation.x, myLocation.y); super.setLocation(x,y); fireActionPerformed(p); } public Point getLocation() { return myLocation; } public int getHeight() { return myHeight; } public int getWidth() { return myWidth; } public void setHeight(int h) { myHeight = h; } public void setWidth(int w) { myWidth = w; } public String getDirection() { return myDirection; } public void setDirection(String dir) { myDirection = dir; } public void setPointerLocation(String dir, JawaaGraphNode n) { Point p = n.getLocation(); int h = n.getHeight(); int w = n.getWidth(); int x ; int y ; myDirection = dir; if (myDirection.equals("N")) { x = p.x; y = p.y - h - myHeight/2; setLocation(x,y); } else if (myDirection.equals("S")) { x = p.x; y = p.y + h + myHeight/2; setLocation(x,y); } else if (myDirection.equals("E")) { x = p.x + w + myWidth/2; y = p.y; setLocation(x,y); } else if (myDirection.equals("W")) { x = p.x - w - myWidth/2; y = p.y; setLocation(x,y); } else if (myDirection.equals("NW")) { x = p.x - w - w/2; y = p.y - h - myHeight; setLocation(x,y); } else if (myDirection.equals("NE")) { x = p.x + w + w/2; y = p.y - h - myHeight/2; setLocation(x,y); } else if (myDirection.equals("SW")) { x = p.x - w - w/2; y = p.y + h + myHeight/2; setLocation(x,y); } else if (myDirection.equals("SE")) { x = p.x + w + w/2; y = p.y + h + myHeight/2; setLocation(x,y); } else ErrorHandler.error(this, "not a valid direction"); myConnection = n; } public JawaaGraphNode getConnectedNode () { return myConnection; } public SmartArrow addChild(JawaaGraphNode n, Color c) { SmartArrow temp = new SmartArrow(this, n, c); n.addPointer(temp); myArrows.addElement(temp); myArrowColor = c; return temp; } public SmartArrow addChild(JawaaGraphNode n, Color c, int j) { SmartArrow temp = new SmartArrow(this, n, c, j); n.addPointer(temp); myArrows.addElement(temp); myArrowColor = c; return temp; } public Color getArrowColor() { return myArrowColor; } public void setArrowColor(Color c) { myArrowColor = c; } public void paint(Graphics g) { super.paint(g); } /** * stores instances of the arrows that are pointing at this * particular node **/ public void addPointer(SmartArrow arrow) { myPointers.addElement(arrow); } /***************************** * ArrowMonger interface functions *****************************/ public void addArrowListener(PositionListener listen) { myListeners.addElement(listen); } public void removeArrowListener(PositionListener listen) { myListeners.removeElement(listen); myPointers.removeElement(listen); myArrows.removeElement(listen); } public void fireActionPerformed(Point p) { for(int i=0; i< myListeners.size(); i++) { ((PositionListener)myListeners.elementAt(i)).pointMoved(); } } public Point getArrowConnection(SmartArrow a) { Point destin = ((JawaaShape)a.getNext()).getCenter(); Point init = getCenter(); if(myOutline instanceof JawaaRectangle) return getRectHandle(calcLineAngle(init, destin)); else return getCircleHandle(calcLineAngle(init, destin)); } public Point getArrowPoint(SmartArrow a) { Point init = getCenter(); Point destin = ((JawaaShape)a.getPrevious()).getCenter(); if(myOutline instanceof JawaaRectangle) return getRectHandle(calcLineAngle(init, destin)); else return getCircleHandle(calcLineAngle(init, destin)); } public Point getArrowPoint() { return new Point(myLocation.x, myLocation.y+myHeight/2); } public Point getArrowConnection() { return new Point(myLocation.x+myWidth, myLocation.y+myHeight/2); } protected Vector myListeners = new Vector(); /****************end ArrowMonger**********************/ /** * @param begin is the starting point * @param end is the ending point * @returns the angle that the line between the two points makes * with the horizontal. The angle is between 0 and 2PI radians. */ private double calcLineAngle(Point begin, Point end) { Point proxy = end; int y = proxy.y - begin.y; int x = proxy.x - begin.x; double angle; if((x == 0) && (y>=0)) angle = (3*Math.PI/2); else if((x == 0) && (y <=0)) angle = (Math.PI/2); else if((x < 0) && (y <= 0)) angle = Math.PI - Math.atan((double)y/(double)x); else if((x < 0) && (y >= 0)) angle = Math.PI + Math.abs(Math.atan((double)y/(double)x)); else if(y > 0) angle = 2*Math.PI - Math.atan((double)y/(double)x); else angle = -1* Math.atan((double)y/(double)x); return angle; } private Point getRectHandle(double angle) { double x = 1; double y = 1; double cutoff = Math.atan(((double)myHeight/2) / ((double)myWidth/2)); if(angle >= Math.PI) { angle = angle - Math.PI; y = y * -1; x = x * -1; } if(angle >= Math.PI-cutoff) { x = (x * -1* (double)myWidth/2.0); y = y * (double)myWidth/2.0 * Math.tan(angle); } else if(angle >= cutoff) { y = -1 * y * (double)myHeight/2.0; x = x * (double)myHeight/2.0 * 1/(Math.tan(angle)); } else { x = x * (double)myWidth/2.0; y = -1 * y * (double)myWidth/2.0 * Math.tan(angle); } return new Point(getCenter().x + (int)Math.rint(x), getCenter().y +(int)Math.rint(y)); } private Point getCircleHandle(double angle) { int x = myWidth/2; int y = myHeight/2; x = (int)(Math.rint(x * Math.cos(angle))); y = -1* (int)(Math.rint(y * Math.sin(angle))); return new Point(getCenter().x +x, getCenter().y +y); } /************************************ ** Marker Interface ************************************/ public int addMarkerListener(JawaaMarker mark) { myListeners.addElement(mark); return ++myNumMarkers; } public void removeMarkerListener(JawaaMarker mark) { if(myListeners.removeElement(mark)) { myNumMarkers--; } } public Point getMarkerHandle(int index) { return getCenter(); } protected Point[] calcLocations() { return null; } protected double getAvgDiameter() { double diam = 0.0; for(int i = 0; i < myMarkers.size(); i++) diam += ((JawaaMarker)myMarkers.elementAt(i)).getSize()[0]; return diam/myMarkers.size(); } private Point[] myPositions; private int myNumMarkers = 0; private double myAvgDiam; /******* end marker interface *******/ public SmartArrow getArrowToNode(Markable node) { for(int i=0; i