Java Source Code: edu.berkeley.guir.prefuse.render.TextItemRenderer


   1: package edu.berkeley.guir.prefuse.render;
   2: 
   3: import java.awt.Font;
   4: import java.awt.FontMetrics;
   5: import java.awt.Graphics2D;
   6: import java.awt.Shape;
   7: import java.awt.geom.Point2D;
   8: import java.awt.geom.Rectangle2D;
   9: import java.awt.geom.RectangularShape;
  10: import java.awt.geom.RoundRectangle2D;
  11: 
  12: import edu.berkeley.guir.prefuse.VisualItem;
  13: import edu.berkeley.guir.prefuse.util.FontLib;
  14: import edu.berkeley.guir.prefuse.util.StringAbbreviator;
  15: 
  16: /**
  17:  * Renders an item as a text string. The text string used by default is the
  18:  * value of the "label" attribute. To use a different attribute, use the
  19:  * <code>setTextAttributeName</code> method. To perform custom String
  20:  * selection, simply subclass this Renderer and override the 
  21:  * <code>getText</code> method.
  22:  * 
  23:  * @version 1.0
  24:  * @author <a href="http://jheer.org">Jeffrey Heer</a> prefuse(AT)jheer.org
  25:  */
  26:	  public class TextItemRenderer extends ShapeRenderer {
  27:
  28:    public static final int ALIGNMENT_LEFT   = 0;
  29:    public static final int ALIGNMENT_RIGHT  = 1;
  30:    public static final int ALIGNMENT_CENTER = 2;
  31:    public static final int ALIGNMENT_BOTTOM = 1;
  32:    public static final int ALIGNMENT_TOP    = 0;
  33:
  34:    protected String m_labelName = "label";
  35:    protected int m_xAlign = ALIGNMENT_CENTER;
  36:    protected int m_yAlign = ALIGNMENT_CENTER;
  37:    protected int m_horizBorder = 3;
  38:    protected int m_vertBorder = 0;
  39:
  40:    protected int m_maxTextWidth = -1;
  41:    protected int m_abbrevType = StringAbbreviator.TRUNCATE;
  42:    protected StringAbbreviator m_abbrev = StringAbbreviator.getInstance();
  43:    
  44:    protected RectangularShape m_textBox  = new Rectangle2D.Float();
  45:    protected Font m_font = FontLib.getFont("SansSerif", Font.PLAIN, 10);
  46:    
  47:    protected Point2D     m_tmpPoint = new Point2D.Float();
  48:
  49:	      public TextItemRenderer() {
  50:    } //
  51:
  52:    /**
  53:     * Sets the default font used by this Renderer. If calling getFont() on
  54:     * a VisualItem returns a non-null value, the returned Font will be used
  55:     * instead of this default one.
  56:     * @param f the default font to use. Note that this will ONLY be used when
  57:     * if a VisualItem's getFont() method returns null.
  58:     */
  59:	      public void setFont(Font f) {
  60:        m_font = f;
  61:    } //
  62:    
  63:    /**
  64:     * Rounds the corners of the bounding rectangle in which the text
  65:     * string is rendered.
  66:     * @param arcWidth the width of the curved corner
  67:     * @param arcHeight the height of the curved corner
  68:     */
  69:	      public void setRoundedCorner(int arcWidth, int arcHeight) {
  70:        if ( (arcWidth == 0 || arcHeight == 0) && 
  71:	              !(m_textBox instanceof Rectangle2D) ) {
  72:            m_textBox = new Rectangle2D.Float();
  73:        } else {
  74:            if ( !(m_textBox instanceof RoundRectangle2D) )
  75:                m_textBox = new RoundRectangle2D.Float();
  76:            ((RoundRectangle2D)m_textBox)
  77:                .setRoundRect(0,0,10,10,arcWidth,arcHeight);                    
  78:        }
  79:    } //
  80:
  81:    /**
  82:     * Get the attribute name of the text to draw.
  83:     * @return the text tattribute name
  84:     */
  85:	      public String getTextAttributeName() {
  86:        return m_labelName;
  87:    } //
  88:    
  89:    /**
  90:     * Set the attribute name for the text to draw.
  91:     * @param name the text attribute name
  92:     */
  93:	      public void setTextAttributeName(String name) {
  94:        m_labelName = name;
  95:    } //
  96:
  97:    /**
  98:     * Sets the maximum width that should be allowed of the text label.
  99:     * A value of -1 specifies no limit (this is the default).
 100:     * @param maxWidth the maximum width of the text or -1 for no limit
 101:     */
 102:	      public void setMaxTextWidth(int maxWidth) {
 103:        m_maxTextWidth = maxWidth;
 104:    } //
 105:    
 106:    /**
 107:     * Sets the type of abbreviation to be used if a text label is longer
 108:     * than the maximum text width. The value should be one of the constants
 109:	       * provided by the {@link edu.berkeley.guir.prefuse.util.StringAbbreviator
 110:     * StringAbbreviator} class. To enable abbreviation, you must first set
 111:	       * the maximum text width using the {@link #setMaxTextWidth(int) 
 112:     * setMaxTextWidth} method.
 113:     * @param abbrevType the abbreviation type to use. Should be one of the
 114:     * constants provided by the 
 115:	       * {@link edu.berkeley.guir.prefuse.util.StringAbbreviator
 116:     * StringAbbreviator} class (e.g. StringAbbreviator.TRUNCATE or 
 117:     * StringAbbreviator.NAME).
 118:     */
 119:	      public void setAbbrevType(int abbrevType) {
 120:        m_abbrevType = abbrevType;
 121:    } //
 122:    
 123:    /**
 124:     * Returns the text to draw. Subclasses can override this class to
 125:     * perform custom text rendering.
 126:     * @param item the item to represent as a <code>String</code>
 127:     * @return a <code>String</code> to draw
 128:     */
 129:	      protected String getText(VisualItem item) {
 130:        String s =  (String)item.getAttribute(m_labelName);
 131:	          if ( m_maxTextWidth > -1 ) {
 132:            Font font = item.getFont();
 133:            if ( font == null ) { font = m_font; }
 134:            FontMetrics fm = DEFAULT_GRAPHICS.getFontMetrics(font);
 135:	              if ( fm.stringWidth(s) > m_maxTextWidth ) {
 136:                s = m_abbrev.abbreviate(s, m_abbrevType, fm, m_maxTextWidth);            
 137:            }
 138:        }
 139:        return s;
 140:    } //
 141:    
 142:	      protected boolean isHyperlink(VisualItem item) {
 143:        Boolean b = (Boolean)item.getVizAttribute(m_labelName + "_LINK");
 144:        return ( b != null && Boolean.TRUE.equals(b) );
 145:    } //
 146:
 147:    /**
 148:     * @see edu.berkeley.guir.prefuse.render.ShapeRenderer#getRawShape(edu.berkeley.guir.prefuse.VisualItem)
 149:     */
 150:	      protected Shape getRawShape(VisualItem item) {
 151:        String s = getText(item);
 152:        if ( s == null ) { s = ""; }
 153:        m_font = item.getFont();
 154:        
 155:        // make renderer size-aware
 156:        double size = item.getSize();
 157:        if ( size != 1 )
 158:            m_font = FontLib.getFont(m_font.getName(), m_font.getStyle(),
 159:                    size*m_font.getSize());
 160:        
 161:        FontMetrics fm = DEFAULT_GRAPHICS.getFontMetrics(m_font);
 162:        double h = fm.getHeight() + size*2*m_vertBorder;
 163:        double w = fm.stringWidth(s) + size*2*m_horizBorder;
 164:        getAlignedPoint(m_tmpPoint, item, w, h, m_xAlign, m_yAlign);
 165:        m_textBox.setFrame(m_tmpPoint.getX(),m_tmpPoint.getY(),w,h);
 166:        return m_textBox;
 167:    } //
 168:    
 169:    /**
 170:     * Helper method, which calculates the top-left co-ordinate of a node
 171:     * given the node's alignment.
 172:     */
 173:    protected static void getAlignedPoint(Point2D p, VisualItem item, 
 174:            double w, double h, int xAlign, int yAlign)
 175:	      {
 176:        double x = item.getX(), y = item.getY();
 177:	          if ( xAlign == ALIGNMENT_CENTER ) {
 178:            x = x-(w/2);
 179:        } else if ( xAlign == ALIGNMENT_RIGHT ) {
 180:            x = x-w;
 181:        }
 182:	          if ( yAlign == ALIGNMENT_CENTER ) {
 183:            y = y-(h/2);
 184:        } else if ( yAlign == ALIGNMENT_BOTTOM ) {
 185:            y = y-h;
 186:        }
 187:        p.setLocation(x,y);
 188:    } //
 189:
 190:    /**
 191:     * @see edu.berkeley.guir.prefuse.render.Renderer#render(java.awt.Graphics2D, edu.berkeley.guir.prefuse.VisualItem)
 192:     */
 193:	      public void render(Graphics2D g, VisualItem item) {
 194:        Shape shape = getShape(item);
 195:	          if ( shape != null ) {
 196:            super.drawShape(g, item, shape);
 197:        
 198:            // now render the text
 199:            String s = getText(item);
 200:	              if ( s != null ) {            
 201:                Rectangle2D r = shape.getBounds2D();
 202:                g.setPaint(item.getColor());
 203:                g.setFont(m_font);
 204:                FontMetrics fm = g.getFontMetrics();
 205:                double size = item.getSize();
 206:                double x = r.getX() + size*m_horizBorder;
 207:                double y = r.getY() + size*m_vertBorder;
 208:                g.drawString(s, (float)x, (float)y+fm.getAscent());
 209:	                  if ( isHyperlink(item) ) {
 210:                    int lx = (int)Math.round(x), ly = (int)Math.round(y);
 211:                    g.drawLine(lx,ly,lx+fm.stringWidth(s),ly+fm.getHeight()-1);
 212:                }
 213:            }
 214:        }
 215:    } //
 216:    
 217:    /**
 218:     * Get the horizontal alignment of this node with respect to it's
 219:     * location co-ordinate.
 220:     * @return the horizontal alignment
 221:     */
 222:	      public int getHorizontalAlignment() {
 223:        return m_xAlign;
 224:    } //
 225:    
 226:    /**
 227:     * Get the vertical alignment of this node with respect to it's
 228:     * location co-ordinate.
 229:     * @return the vertical alignment
 230:     */
 231:	      public int getVerticalAlignment() {
 232:        return m_yAlign;
 233:    } //
 234:    
 235:    /**
 236:     * Set the horizontal alignment of this node with respect to it's
 237:     * location co-ordinate.
 238:     * @param align the horizontal alignment
 239:     */    
 240:	      public void setHorizontalAlignment(int align) {
 241:        m_xAlign = align;
 242:    } //
 243:    
 244:    /**
 245:     * Set the vertical alignment of this node with respect to it's
 246:     * location co-ordinate.
 247:     * @param align the vertical alignment
 248:     */    
 249:	      public void setVerticalAlignment(int align) {
 250:        m_yAlign = align;
 251:    } //
 252:    
 253:    /**
 254:     * Returns the amount of padding in pixels between text 
 255:     * and the border of this item along the horizontal dimension.
 256:     * @return the horizontal padding
 257:     */
 258:	      public int getHorizontalPadding() {
 259:        return m_horizBorder;
 260:    } //
 261:    
 262:    /**
 263:     * Sets the amount of padding in pixels between text 
 264:     * and the border of this item along the horizontal dimension.
 265:     * @param xpad the horizontal padding to set
 266:     */
 267:	      public void setHorizontalPadding(int xpad) {
 268:        m_horizBorder = xpad;
 269:    } //
 270:    
 271:    /**
 272:     * Returns the amount of padding in pixels between text 
 273:     * and the border of this item along the vertical dimension.
 274:     * @return the vertical padding
 275:     */
 276:	      public int getVerticalPadding() {
 277:        return m_vertBorder;
 278:    } //
 279:    
 280:    /**
 281:     * Sets the amount of padding in pixels between text 
 282:     * and the border of this item along the vertical dimension.
 283:     * @param ypad the vertical padding
 284:     */
 285:	      public void setVerticalPadding(int ypad) {
 286:        m_vertBorder = ypad;
 287:    } //
 288:    
 289:} // end of class TextItemRenderer