// Copyright (c) 1996-98 The Regents of the University of California. All // Rights Reserved. Permission to use, copy, modify, and distribute this // software and its documentation for educational, research and non-profit // purposes, without fee, and without a written agreement is hereby granted, // provided that the above copyright notice and this paragraph appear in all // copies. Permission to incorporate this software into commercial products may // be obtained by contacting the University of California. David F. Redmiles // Department of Information and Computer Science (ICS) University of // California Irvine, California 92697-3425 Phone: 714-824-3823. This software // program and documentation are copyrighted by The Regents of the University // of California. The software program and documentation are supplied "as is", // without any accompanying services from The Regents. The Regents do not // warrant that the operation of the program will be uninterrupted or // error-free. The end-user understands that the program was developed for // research purposes and is advised not to rely exclusively on the program for // any reason. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, // INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS // DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY // DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE // SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, // ENHANCEMENTS, OR MODIFICATIONS. // File: NetNode.java // Classes: NetNode // Original Author: ics125b spring 1996 // $Id: NetNode.java,v 1.19 1997/06/10 23:43:16 jrobbins Exp $ package uci.graphedit; import java.awt.*; import java.io.*; import java.util.*; /** This class models a node in our underlying connected graph * model. Nodes have ports that are their connection points to other * nodes. Arcs from one port to another. * * FEATURE: graph_representation_nodes * * @see NetArc * @see NetPort */ public class NetNode extends NetPrimitive { //////////////////////////////////////////////////////////////// // instance variables /** An array of the ports on this node */ protected NetPort portList[]; /** Number ports on this node */ protected int numPorts; /** Nodes may have a list of predefined Perspective's that give the * node different looks. Needs-More-Work: This code is not fully * operational right now. */ protected Hashtable _perspectives = new Hashtable(); //////////////////////////////////////////////////////////////// // constructors and related methods /** Construct a new node from the given default node and number of * ports. The attributes of the default node will be used if they * are not overridden in this node (i.e., nodes have attributes and * there is a virual copy relationship between some nodes). */ public NetNode(NetNode deft, int nPorts) { numPorts = nPorts; portList = new NetPort[nPorts]; } /** Construct a new NetNode with no default attributes and no ports. */ public NetNode() { this(null, 0); } /** Usually when nodes are created it is deon through newInstance * and there is no chance to supply a default node or to connect * this node to some other application level object. So after a * node is constructed initialize is called to supply that * information.
* * Needs-More-Work: what is the class protocol design here? */ public void initialize(NetNode default_node, Object model) { } //////////////////////////////////////////////////////////////// // accessors /** Returns the attribute table of the node. */ public Object getAttributes() { return null; } /** reply my NetPort with the given index. */ public NetPort getPort(int i) { return portList[i]; } /** returns the perspectiveList */ public Hashtable getPerspectives() { return _perspectives; } //////////////////////////////////////////////////////////////// // Editor API /** Remove this node from the underling connected graph model. */ public void dispose() { //System.out.println("disposing: " + toString()); for (int i = 0; i < numPorts; ++i) { if (portList[i] != null) portList[i].dispose(); } Vector v = new Vector(2); v.addElement(Globals.REMOVE); v.addElement(this); setChanged(); notifyObservers(v); } //////////////////////////////////////////////////////////////// // Visualization related methods /** Reply the perspective that is appropriate for visualizing this * node in the given Layer. If no such perspective already exists, * instanciate a new one. */ public Perspective perspectiveFor(Layer lay) { Perspective p = (Perspective)_perspectives.get(lay); if (null == p) { p = makePerspective(lay); if (p != null) _perspectives.put(lay, p); } return p; } /** Construct and return a new Perspective to present this NetNode * in the given Layer. A default implementation is supplied as an * example, but all subclasses should override this method. NetPorts * of this NetNode should be associated with individual Figs that * make up the Perspective. */ public Perspective makePerspective(Layer lay) { Fig obj1 = new FigRect(-25, -25, 50, 50, Color.black, Color.white); Fig obj2 = new FigCircle(-20, -20, 40, 40, Color.red); Fig obj3 = new FigCircle( -5, -30, 10, 10, Color.black, Color.blue); Fig obj4 = new FigCircle( -5, 20, 10, 10, Color.black, Color.blue); Fig obj5 = new FigRect(-30, -5, 10, 10, Color.black, Color.green); Fig obj6 = new FigRect( 20, -5, 10, 10, Color.black, Color.green); FigList temp_list = new FigList(); temp_list.addFig(obj1); temp_list.addFig(obj2); temp_list.addFig(obj3); temp_list.addFig(obj4); temp_list.addFig(obj5); temp_list.addFig(obj6); Perspective pers1 = new Perspective(this, temp_list); pers1.addPort(portList[0], obj3); pers1.addPort(portList[1], obj4); pers1.addPort(portList[2], obj5); pers1.addPort(portList[3], obj6); return pers1; } //////////////////////////////////////////////////////////////// // event handlers /** NetNode's can process events. If the Editor does not want to * process an Event and the Editor's current Mode does not want to * process it, then the Event is passed to the NetNode under the * mouse, if there is one. This allows nodes to react to user * input to do application specific actions. By default all of * these event handlers do nothing and return false. By * convention, event handlers in subclasses should call the * handler in their superclass if the choose not to handle an * event. */ /** This event handler is defined to call editNode when the user * clicks the right-hand mouse button on a Perspective. */ public boolean mouseUp(Event e, int x, int y) { if ((e.modifiers | Event.META_MASK) != 0) { Editor ce = Globals.curEditor(); ActionEditNode act = new ActionEditNode(this); ce.executeAction(act, e); return true; } return false; } /** Pop up a meny showing a list of options/commands for this * node. This is not currently availible because AWT 1.0.2 does not * support pop up menus. */ public void popNodeMenu() { System.out.println("now showing a menu of node options"); } /** Edit this NetNode in some application specific way. Typically * open a dialog box to edit some attributes of the * node. Needs-More-Work: shuold provide a default attribute editor * for my system of node attributes. */ public void editNode() { Globals.startPropertySheet(); Globals.curEditor().updatePropertySheet(); } //////////////////////////////////////////////////////////////// // net-level hooks /** Do some application specific action just after this node is * connected to another node. the arguments contain some info about * what ports were connected. */ public void postConnect(NetNode anotherNode, NetPort myPort, NetPort otherPort) { } /** Do some application specific action just after this node is * disconnected from another node. the arguments contain some info * about what ports were connected. */ public void postDisconnect(NetNode anotherNode, NetPort myPort, NetPort otherPort) { } //////////////////////////////////////////////////////////////// // net-level constraints /** Allow foir application specific rules about which nodes can be * connected to which other nodes. This is called from the NetPort, * so the port has first say as to whether it can be connected to * some other port. NetPort.canConnectTo() just calls * NetNode.canConnectTo(). By default anything can be connected to * anything. */ public boolean canConnectTo(NetNode otherNode, NetPort otherPort, NetPort myPort) { return true; } //////////////////////////////////////////////////////////////// // diagram-level hooks /** Do some application specific actions after the node is placed in * a drawing area. */ public void postPlacement(Editor ed) { } } /* end class NetNode */