    001: import java.awt.Dimension;
    002: import java.awt.Graphics2D;
    003: import java.awt.geom.Rectangle2D;
    004: import java.io.Serializable;
    005: import java.util.StringTokenizer;
    006:
    007: import javax.swing.JLabel;
    008:
    009: /**
    010:    A string that can extend over multiple lines.
    011: */
    012: public class MultiLineString implements Cloneable, Serializable
    013: {
    014:    /**
    015:       Constructs an empty, centered, normal size multiline
    016:       string that is not underlined.
    017:    */
    018:    public MultiLineString()
    019:    {
    020:       text = "";
    021:       justification = CENTER;
    022:       size = NORMAL;
    023:       underlined = false;
    024:    }
    025:    /**
    026:       Sets the value of the text property.
    027:       @param newValue the text of the multiline string
    028:    */
    029:    public void setText(String newValue) { text = newValue; }
    030:    /**
    031:       Gets the value of the text property.
    032:       @return the text of the multiline string
    033:    */
    034:    public String getText() { return text; }
    035:    /**
    036:       Sets the value of the justification property.
    037:       @param newValue the justification, one of LEFT, CENTER,
    038:       RIGHT
    039:    */
    040:    public void setJustification(int newValue) { justification = newValue; }
    041:    /**
    042:       Gets the value of the justification property.
    043:       @return the justification, one of LEFT, CENTER,
    044:       RIGHT
    045:    */
    046:    public int getJustification() { return justification; }
    047:    /**
    048:       Gets the value of the underlined property.
    049:       @return true if the text is underlined
    050:    */
    051:    public boolean isUnderlined() { return underlined; }
    052:    /**
    053:       Sets the value of the underlined property.
    054:       @param newValue true to underline the text
    055:    */
    056:    public void setUnderlined(boolean newValue) { underlined = newValue; }
    057:    /**
    058:       Sets the value of the size property.
    059:       @param newValue the size, one of SMALL, NORMAL, LARGE
    060:    */
    061:    public void setSize(int newValue) { size = newValue; }
    062:    /**
    063:       Gets the value of the size property.
    064:       @return the size, one of SMALL, NORMAL, LARGE
    065:    */
    066:    public int getSize() { return size; }
    067:
    068:    public String toString()
    069:    {
    070:       return text.replace('\n', '|');
    071:    }
    072:
    073:    private void setLabelText()
    074:    {
    075:       StringBuffer prefix = new StringBuffer();
    076:       StringBuffer suffix = new StringBuffer();
    077:       StringBuffer htmlText = new StringBuffer();
    078:       prefix.append("&nbsp;");
    079:       suffix.insert(0, "&nbsp;");
    080:       if (underlined)
    081:       {
    082:          prefix.append("<u>");
    083:          suffix.insert(0, "</u>");
    084:       }
    085:       if (size == LARGE)
    086:       {
    087:          prefix.append("<font size=\"+1\">");
    088:          suffix.insert(0, "</font>");
    089:       }
    090:       if (size == SMALL)
    091:       {
    092:          prefix.append("<font size=\"-1\">");
    093:          suffix.insert(0, "</font>");
    094:       }
    095:       htmlText.append("<html>");
    096:       StringTokenizer tokenizer = new StringTokenizer(text, "\n");
    097:       boolean first = true;
    098:       while (tokenizer.hasMoreTokens())
    099:       {
    100:          if (first) first = false; else htmlText.append("<br>");
    101:          htmlText.append(prefix);
    102:          htmlText.append(tokenizer.nextToken());
    103:          htmlText.append(suffix);
    104:       }
    105:       htmlText.append("</html>");
    106:       label.setText(htmlText.toString());
    107:       if (justification == LEFT) label.setHorizontalAlignment(JLabel.LEFT);
    108:       else if (justification == CENTER) label.setHorizontalAlignment(JLabel.CENTER);
    109:       else if (justification == RIGHT) label.setHorizontalAlignment(JLabel.RIGHT);
    110:    }
    111:
    112:    /**
    113:       Gets the bounding rectangle for this multiline string.
    114:       @param g2 the graphics context
    115:       @return the bounding rectangle (with top left corner (0,0))
    116:    */
    117:    public Rectangle2D getBounds(Graphics2D g2)
    118:    {
    119:       if (text.length() == 0) return new Rectangle2D.Double();
    120:       setLabelText();
    121:       Dimension dim = label.getPreferredSize();
    122:       return new Rectangle2D.Double(0, 0, dim.getWidth(), dim.getHeight());
    123:    }
    124:
    125:    /**
    126:       Draws this multiline string inside a given rectangle
    127:       @param g2 the graphics context
    128:       @param r the rectangle into which to place this multiline string
    129:    */
    130:    public void draw(Graphics2D g2, Rectangle2D r)
    131:    {
    132:       setLabelText();
    133:       label.setFont(g2.getFont());
    134:       label.setBounds(0, 0, (int) r.getWidth(), (int) r.getHeight());
    135:       g2.translate(r.getX(), r.getY());
    136:       label.paint(g2);
    137:       g2.translate(-r.getX(), -r.getY());
    138:    }
    139:
    140:    public Object clone()
    141:    {
    142:       try
    143:       {
    144:          return super.clone();
    145:       }
    146:       catch (CloneNotSupportedException exception)
    147:       {
    148:          return null;
    149:       }
    150:    }
    151:
    152:    public static final int LEFT = 0;
    153:    public static final int CENTER = 1;
    154:    public static final int RIGHT = 2;
    155:    public static final int LARGE = 3;
    156:    public static final int NORMAL = 4;
    157:    public static final int SMALL = 5;
    158:
    159:    private static final int GAP = 3;
    160:
    161:    private String text;
    162:    private int justification;
    163:    private int size;
    164:    private boolean underlined;
    165:
    166:    private static JLabel label = new JLabel();
    167: }