// $Id: DrawableNode.java,v 3.1 1998/12/01 14:18:57 te3d Exp $
////////////////////////////////////////////////////////////////////////////
//
// File: DrawableNode.java
//
// Purpose: A DrawableNode is a graphical representation of
// a Node. Properties:
//
// o Elliptical shape
// o Name - label
// o Recovery - not visible (only in Details window)
// o Stable - green border is stable, red is unstable
//
// This is a base class, and can used by several modules.
// For that reason, we don't specify the Invoking modules.
//
// Authors:
// txe Travis Emmitt emmitt@virginia.edu
//
// Modifications:
// 28-OCT-1998 txe (v1) Initial creation (was screen.Node)
// 29-OCT-1998 txe Removed Toggle
// 03-NOV-1998 txe Added comments, removed unused methods.
// 06-NOV-1998 rgb Added version control header info
//
// 13-NOV-1998 txe (v2) Extends Node, added exceptions
// 15-NOV-1998 txe Added new exceptions
// 16-NOV-1998 txe Added exceptions, comments, constants
//
// 30-NOV-1998 txe (v3) Improved format, speed
//
////////////////////////////////////////////////////////////////////////////
import java.applet.*;
import java.awt.*;
public class DrawableNode extends Node {
private int x; // X coordinate of northwest corner
private int y; // Y coordinate of northwest corner
private int w; // width
private int h; // height
private final static int
MAX_LABEL_LEN = 10, // maximum label length (truncate)
MIN_FILL_WIDTH = 20, // how big must it be to deserve fill&label
NORMAL_MODE = 0, // normal viewing mode
SHOW_ALL_NODES = 1, // mode option: show all nodes
DEPENDEE_MODE = 2, // mode option: we're a dependee
DEPENDER_MODE = 3; // mode option: we're a depender
private final static Color
LABEL_COLOR = new Color (0.0f, 0.0f, 0.0f), // black
STABLE_FCOLOR = new Color (0.3f, 0.6f, 0.3f), // dk green
STABLE_BCOLOR = new Color (0.8f, 1.0f, 0.9f), // lt green
UNSTABLE_FCOLOR = new Color (0.6f, 0.3f, 0.3f), // dk red
UNSTABLE_BCOLOR = new Color (0.9f, 0.5f, 0.5f), // lt red
DEPENDEE_FCOLOR = new Color (1.0f, 0.9f, 1.0f), // white
DEPENDEE_BCOLOR = new Color (0.9f, 0.2f, 0.2f), // red
DEPENDER_FCOLOR = new Color (0.0f, 0.3f, 0.0f), // dk green
DEPENDER_BCOLOR = new Color (1.0f, 1.0f, 0.5f); // yellow
///////////////////////////////////////////////////////////////////
//
// Method: DrawableNode [constructor]
//
// Purpose: This creates a new DrawableNode representing the
// specified Node, with the specified bounds.
//
///////////////////////////////////////////////////////////////////
public DrawableNode (Node new_node, int new_bounds[])
throws BoundsException, IndexException, NullException {
if (new_node == null) {
throw new NullException ("new_node");
}
if (new_bounds == null) {
throw new NullException ("new_bounds");
}
Copy (new_node);
int i = 0;
try {
x = new_bounds[i++];
y = new_bounds[i++];
w = new_bounds[i++];
h = new_bounds[i++];
}
catch (Exception e) {
throw new IndexException ("new_bounds", i);
}
}
///////////////////////////////////////////////////////////////////
//
// Method: Draw
//
// Purpose: This displays the Node on the screen.
// The mode is used for handling special display
// cases (see constants at top).
//
///////////////////////////////////////////////////////////////////
public void Draw (Graphics graphics, int mode)
throws GraphicsException, NullException {
if (graphics == null) {
throw new NullException ("graphics");
}
int font_size = (w / MAX_LABEL_LEN) * 2;
int label_len = Math.min (name.length(), MAX_LABEL_LEN);
String label = name.substring (0, label_len);
int label_x = GetCenterX() - ((font_size * label_len) / 4);
int label_y = GetCenterY() + (font_size / 2);
Color edge_color = null;
Color fill_color = null;
Color label_color = null;
if (mode == SHOW_ALL_NODES) {
edge_color = (stable ? STABLE_FCOLOR : UNSTABLE_FCOLOR);
fill_color = edge_color;
label_color = null;
}
else if (mode == DEPENDEE_MODE) {
edge_color = DEPENDEE_FCOLOR;
fill_color = DEPENDEE_BCOLOR;
label_color = edge_color;
}
else if (mode == DEPENDER_MODE) {
edge_color = DEPENDER_FCOLOR;
fill_color = DEPENDER_BCOLOR;
label_color = edge_color;
}
else {
edge_color = (stable ? STABLE_FCOLOR : UNSTABLE_FCOLOR);
fill_color = (stable ? STABLE_BCOLOR : UNSTABLE_BCOLOR);
label_color = LABEL_COLOR;
}
try {
graphics.setColor (fill_color);
graphics.fillOval (x, y, w, h);
graphics.setColor (edge_color);
graphics.drawOval (x, y, w, h);
if (label_color != null) {
graphics.setColor (label_color);
graphics.setFont (new Font ("Helvetica", Font.PLAIN, font_size));
graphics.drawString (label, label_x, label_y);
}
}
catch (Exception e) {
throw new GraphicsException (e);
}
}
///////////////////////////////////////////////////////////////////
//
// Method: GetCenterX
//
// Purpose: Returns X coordinate of center of Node.
//
///////////////////////////////////////////////////////////////////
public int GetCenterX () {
return x + (w / 2);
}
///////////////////////////////////////////////////////////////////
//
// Method: GetY
//
// Purpose: Returns Y coordinate of center of Node.
//
///////////////////////////////////////////////////////////////////
public int GetCenterY () {
return y + (h / 2);
}
///////////////////////////////////////////////////////////////////
//
// Method: Inside
//
// Purpose: This returns true if the specified coordinate
// is within the DrawableNode (assumes elliptical shape),
// false otherwise.
//
///////////////////////////////////////////////////////////////////
public boolean Inside (int new_x, int new_y) {
double dx = new_x - GetCenterX ();
double dy = new_y - GetCenterY ();
dy = (double) (dy * w) / (double) Math.max (h, 1);
return (Math.sqrt ((dx * dx) + (dy * dy)) < (double) w / 2);
}
}
////////////////////////////////////////////////////////////////////////////