/* ComBox.java */ package ciips.animation; import java.awt.*; import java.awt.font.*; import java.awt.geom.*; import java.lang.*; /** * This class composes a commentary box to be drawn on any drawing panel/canvas. * The width of the commentary box will be determined by the length of the * text string being displayed. *

* Since this object implements DrawingObj, it can be added * into the DrawingPanel by using either the addCom * or addDrawingObj method. An added commentary box can be * removed by calling the removeCom or removeObj * method of the DrawingPanel class. *

* If the addCom method * is called, the added commentary box is guaranteed to be displayed on * top of all drawing objects added to the panel using * addDrawingObj. * Otherwise, if the commentary box is added to the panel using * addDrawingObj, the last added object will be on top. *

* Typically, a commentary box can be initialized and added to a * drawing panel and displayed by using the following statements: *

 *			ComBox com = new ComBox(x, y, "Example Comment", font);
 *			drawingPanel.addCom(com);
 *			drawingPanel.redraw();
 * 
* It is removed from the drawing panel by: *
 *			drawingPanel.removeCom(com);
 * 
* where drawingPanel is an instance of the class object * DrawingPanel, x and y define * the top left position of the commentary box and font * is an instance of the Font object, typically a fixed font, * which is declared as follows: *
 *			Font font = new Font("Courier", Font.PLAIN, 12);
 * 
* Note that the size-12 courier font is recommended for all situations * since the width of the com box is calculated based on this particular * size font. Otherwise, the dimension has to be modified. * * @see DrawingPanel * @see DrawingPanel#addCom * @see DrawingPanel#addDrawingObj * @see DrawingPanel#redraw */ public class ComBox extends Drawable { private Point topLeft; private int height, width; private Font font; private int[] xPts, yPts; private int nPts; private Color bg; private Color fg; private static final Font def_font = new Font( "Courier", Font.PLAIN, 12 ); /** * Creates a commentary box with its topleft corner at (topLeftX, topLeftY) * and the commentary text specified by the third String * parameter. By default, the background color is yellow and * the text is displayed in blue. * @param topLeftX Integer value specifying the horizontal position of the * topleft corner of the commentary box. * @param topLeftY Integer value specifying the vertical position of the * topleft corner of the commentary box. * @param str The text string to be displayed on the commentary box. */ public ComBox(int topLeftX, int topLeftY, String str, Font font) { x = topLeftX; y = topLeftY; this.topLeft = new Point(topLeftX, topLeftY); this.label = str; this.fg = Color.blue; this.bg = Color.yellow; this.font = font; height = 30; width = 7*label.length() + 6; nPts = 8; xPts = new int[nPts]; yPts = new int[nPts]; xPts[0] = topLeft.x + 4; xPts[1] = topLeft.x + width - 4; xPts[2] = xPts[3] = topLeft.x + width; xPts[4] = xPts[1]; xPts[5] = xPts[0]; xPts[6] = xPts[7] = topLeft.x; yPts[0] = yPts[1] = topLeft.y; yPts[2] = topLeft.y + 4; yPts[3] = topLeft.y + height - 4; yPts[4] = yPts[5] = topLeft.y + height; yPts[6] = yPts[3]; yPts[7] = yPts[2]; } public ComBox( int tlx, int tly, String s ) { this( tlx, tly, s, def_font ); } /** * Creates a commentary box with its topleft corner at (topLeftX, topLeftY) * and the commentary text specified by the third String * parameter, using the foreground and background colors indicated by * the fourth and fifth parameters. * * @param topLeftX Integer value specifying the horizontal position of the * topleft corner of the commentary box. * @param topLeftY Integer value specifying the vertical position of the * topleft corner of the commentary box. * @param str The text string to be displayed on the commentary box. * @param fg Color of the text in the commentary box. * @param bg Color of the commentary box background. */ public ComBox(int topLeftX, int topLeftY, String str, Color fg, Color bg, Font font) { x = topLeftX; y = topLeftY; this.topLeft = new Point(topLeftX, topLeftY); this.label = str; this.fg = fg; this.bg = bg; this.font = font; height = 30; width = 7*label.length() + 6; nPts = 8; xPts = new int[nPts]; yPts = new int[nPts]; xPts[0] = topLeft.x + 4; xPts[1] = topLeft.x + width - 4; xPts[2] = xPts[3] = topLeft.x + width; xPts[4] = xPts[1]; xPts[5] = xPts[0]; xPts[6] = xPts[7] = topLeft.x; yPts[0] = yPts[1] = topLeft.y; yPts[2] = topLeft.y + 4; yPts[3] = topLeft.y + height - 4; yPts[4] = yPts[5] = topLeft.y + height; yPts[6] = yPts[3]; yPts[7] = yPts[2]; } // Offsets for placing a commentary box "near" another object private static final int x_near_off = 15; private static final int y_near_off = -5; /** * Creates a commentary box near another object * * @param z Drawing object to which this commentary box refers * @param s Comment string */ public ComBox( DrawingObj z, String s ) { this( z.getX()+x_near_off, z.getY()+y_near_off, s ); } /** * Creates a commentary box near another object: use this method * when more than one box may be associated with an object * * @param z Drawing object to which this commentary box refers * @param offset Offset from object * @param s Comment string * @param fg Text colour * @param bg Background colour */ public ComBox( DrawingObj z, Point offset, String s, Color fg, Color bg ) { this( z.getX()+offset.x, z.getY()+offset.y, s, fg, bg, def_font ); } /** * Set the text string to be displayed on the commentary box. * @param str Text string in the form of class String */ public void setText( String str ) { this.label = str; width = 7*label.length() + 6; xPts[0] = topLeft.x + 4; xPts[1] = topLeft.x + width - 4; xPts[2] = xPts[3] = topLeft.x + width; xPts[4] = xPts[1]; xPts[5] = xPts[0]; xPts[6] = xPts[7] = topLeft.x; yPts[0] = yPts[1] = topLeft.y; yPts[2] = topLeft.y + 4; yPts[3] = topLeft.y + height - 4; yPts[4] = yPts[5] = topLeft.y + height; yPts[6] = yPts[3]; yPts[7] = yPts[2]; } public void appendText( String app ) { label = label + app; width = 7*label.length() + 6; } /** * Set the top left position of the commentary box. * @param topLeftX Horizontal position of the top left corner. * @param topLeftY Vertical position of the top left corner. */ public void setTopLeft(int topLeftX, int topLeftY) { x = topLeftX; y = topLeftY; this.topLeft = new Point(topLeftX, topLeftY); xPts[0] = topLeft.x + 4; xPts[1] = topLeft.x + width - 4; xPts[2] = xPts[3] = topLeft.x + width; xPts[4] = xPts[1]; xPts[5] = xPts[0]; xPts[6] = xPts[7] = topLeft.x; yPts[0] = yPts[1] = topLeft.y; yPts[2] = topLeft.y + 4; yPts[3] = topLeft.y + height - 4; yPts[4] = yPts[5] = topLeft.y + height; yPts[6] = yPts[3]; yPts[7] = yPts[2]; } /** * Set the position of the commentary box relative to another object * @param x DrawingObj that the commentary box will 'track' */ public void setTopLeft( DrawingObj z ) { setTopLeft( z.getX()+x_near_off, z.getY()+y_near_off ); } /** * Set the background color of the commentary box. * The background color of commentary box is specified by * java.awt.Color. * @param col Background color, instance of java.awt.color * @see Color */ public void setBackground(Color col) { this.bg = col; } /** * Set the text color of the commentary box. * This foreground color (text color) is * specified by * java.awt.Color. * @see Color * @param col Foreground color, instance of java.awt.color */ public void setColor(Color col) { this.fg = col; } /** * This method is to be called from the paint(Graphics g) * method of the drawing panel/canvas. It uses the graphical context * of the drawing panel/canvas to construct the commentary box on * the drawing panel/canvas. * @param g Graphical context from the paint(Graphics g) * method of the drawing panel/canvas. * @see Graphics */ public void draw(Graphics g) { if (label.length() < 1) return; Graphics2D g2d = (Graphics2D)g; /* g.setColor(bg); g.fillPolygon(xPts, yPts, nPts); g.setColor(Color.black); g.drawPolygon(xPts, yPts, nPts); g.setColor(fg); g.setFont(font); g.drawString(label, topLeft.x + 4, topLeft.y + height - 10); */ FontRenderContext frc = g2d.getFontRenderContext(); TextLayout layout = new TextLayout( label, font, frc ); Rectangle2D bounds = layout.getBounds(); double bx = (bounds.getX()); double text_height = bounds.getHeight(); double bly = y + (bounds.getY()) + text_height; bounds.setRect(bounds.getX()+x,bounds.getY()+y, bounds.getWidth(),bounds.getHeight()); System.out.print("ComBox:draw bounds (" + bx + "," + bly + ") [" + bounds.getHeight() + "," + bounds.getWidth() + "]"); System.out.println(" x,y (" + x + "," + y + ")" ); g.setColor(bg); g2d.fillRect( (int)(bx+x-2), (int)(bly /* - text_height +y*/), (int)(bounds.getWidth()+4),(int)(text_height+6)); /** g2d.drawRect( (int)(bx+x), (int)(bly-bounds.getHeight()), (int)(bounds.getWidth()),(int)(bounds.getHeight())); **/ // bounds.draw( g2d ); g.setColor( fg ); g.setColor( Color.black ); layout.draw(g2d, (float)x, (float)(bly+text_height) ); } /** * Move the top left position of the commentary box. * @param x Horizontal position of the top left corner. * @param y Vertical position of the top left corner. * @see ComBox#setTopLeft */ public void move(int x, int y) { setTopLeft(x, y); } /** * This method is called to obtain the current text string to be * displayed in the commentary box. * @return The text string to be displayed on the commentary box. */ public String getText() { return label; } }