Back to index

moin  1.9.0~rc2
TextFigure.java
Go to the documentation of this file.
00001 /*
00002  * @(#)TextFigure.java 5.1
00003  *
00004  */
00005 
00006 package CH.ifa.draw.figures;
00007 
00008 import java.util.*;
00009 import java.awt.*;
00010 import java.io.*;
00011 import CH.ifa.draw.framework.*;
00012 import CH.ifa.draw.standard.*;
00013 import CH.ifa.draw.util.*;
00014 
00020 public  class TextFigure
00021         extends AttributeFigure
00022         implements FigureChangeListener, TextHolder {
00023 
00024     private int               fOriginX;
00025     private int               fOriginY;
00026 
00027     // cache of the TextFigure's size
00028     transient private boolean fSizeIsDirty = true;
00029     transient private int     fWidth;
00030     transient private int     fHeight;
00031 
00032     private String  fText;
00033     private Font    fFont;
00034     private boolean fIsReadOnly;
00035     private int  fAlign;
00036 
00037     private static final int TEXTALIGN_LEFT = 0;
00038     private static final int TEXTALIGN_CENTRE = 1;
00039     private static final int TEXTALIGN_RIGHT = 2;
00040 
00041     private Figure  fObservedFigure = null;
00042     private OffsetLocator fLocator = null;
00043 
00044     private static String fgCurrentFontName  = "Helvetica";
00045     private static int    fgCurrentFontSize  = 12;
00046     private static int    fgCurrentFontStyle = Font.PLAIN;
00047 
00048     /*
00049      * Serialization support.
00050      */
00051     private static final long serialVersionUID = 4599820785949456124L;
00052     private int textFigureSerializedDataVersion = 1;
00053 
00054     public TextFigure() {
00055         fOriginX = 0;
00056         fOriginY = 0;
00057         fFont = createCurrentFont();
00058         setAttribute("FillColor", ColorMap.getColorMap().color("None"));
00059        fAlign = TEXTALIGN_LEFT;
00060         fText = new String("");
00061         fSizeIsDirty = true;
00062     }
00063 
00064     public void moveBy(int x, int y) {
00065         willChange();
00066         basicMoveBy(x, y);
00067         if (fLocator != null)
00068             fLocator.moveBy(x, y);
00069         changed();
00070     }
00071 
00072     protected void basicMoveBy(int x, int y) {
00073         fOriginX += x;
00074         fOriginY += y;
00075     }
00076 
00077     public void basicDisplayBox(Point newOrigin, Point newCorner) {
00078         fOriginX = newOrigin.x;
00079         fOriginY = newOrigin.y;
00080     }
00081 
00082     public Rectangle displayBox() {
00083         Dimension extent = textExtent();
00084         return new Rectangle(fOriginX, fOriginY, extent.width, extent.height);
00085     }
00086 
00087     public Rectangle textDisplayBox() {
00088         return displayBox();
00089     }
00090 
00094     public boolean readOnly() {
00095         return fIsReadOnly;
00096     }
00097 
00101     public void setReadOnly(boolean isReadOnly) {
00102         fIsReadOnly = isReadOnly;
00103     }
00104 
00108     public Font getFont() {
00109         return fFont;
00110     }
00111 
00115     public void setFont(Font newFont) {
00116         willChange();
00117         fFont = newFont;
00118         markDirty();
00119         changed();
00120     }
00121 
00125     public void changed() {
00126         super.changed();
00127         updateLocation();
00128     }
00129 
00134     public Object getAttribute(String name) {
00135         Font font = getFont();
00136         if (name.equals("FontSize"))
00137             return new Integer(font.getSize());
00138         if (name.equals("FontStyle"))
00139             return new Integer(font.getStyle());
00140         if (name.equals("FontName"))
00141             return font.getName();
00142        if (name.equals("TextAlign")) {
00143            switch (fAlign) {
00144            default: return "Left";
00145            case TEXTALIGN_CENTRE: return "Centre";
00146            case TEXTALIGN_RIGHT: return "Right";
00147            }
00148        }
00149         return super.getAttribute(name);
00150     }
00151 
00156     public void setAttribute(String name, Object value) {
00157         Font font = getFont();
00158         if (name.equals("FontSize")) {
00159             Integer s = (Integer)value;
00160             setFont(new Font(font.getName(), font.getStyle(), s.intValue()) );
00161         }
00162         else if (name.equals("FontStyle")) {
00163             Integer s = (Integer)value;
00164             int style = font.getStyle();
00165             if (s.intValue() == Font.PLAIN)
00166                 style = font.PLAIN;
00167             else
00168                 style = style ^ s.intValue();
00169             setFont(new Font(font.getName(), style, font.getSize()) );
00170         }
00171         else if (name.equals("FontName")) {
00172             String n = (String)value;
00173             setFont(new Font(n, font.getStyle(), font.getSize()) );
00174         }
00175        else if (name.equals("TextAlign")) {
00176             String n = (String)value;
00177            if (n.equals("Centre"))
00178               fAlign = TEXTALIGN_CENTRE;
00179            else if (n.equals("Right"))
00180               fAlign = TEXTALIGN_RIGHT;
00181            else
00182               fAlign = TEXTALIGN_LEFT;
00183             changed();
00184        }
00185         else
00186             super.setAttribute(name, value);
00187     }
00188 
00192     public String getText() {
00193         return fText;
00194     }
00195 
00199     public void setText(String newText) {
00200         if (!newText.equals(fText)) {
00201             willChange();
00202             fText = new String(newText);
00203             markDirty();
00204             changed();
00205         }
00206     }
00207 
00211     public boolean acceptsTyping() {
00212         return !fIsReadOnly;
00213     }
00214 
00215     public void drawBackground(Graphics g) {
00216         Rectangle r = displayBox();
00217         g.fillRect(r.x, r.y, r.width, r.height);
00218     }
00219 
00220     public void drawFrame(Graphics g) {
00221         g.setFont(fFont);
00222         g.setColor((Color) getAttribute("TextColor"));
00223         FontMetrics metrics = g.getFontMetrics(fFont);
00224        StringTokenizer st = new StringTokenizer(fText, "\n");
00225        Dimension d = textExtent();
00226        
00227        int orgy = fOriginY;
00228        while (st.hasMoreTokens()) {
00229            String t = st.nextToken();
00230            int xpos = fOriginX;
00231            if (fAlign == TEXTALIGN_RIGHT) {
00232               xpos += d.width - metrics.stringWidth(t);
00233            } else if (fAlign == TEXTALIGN_CENTRE) {
00234               xpos += (d.width - metrics.stringWidth(t)) / 2;
00235            }
00236            g.drawString(t, xpos, orgy + metrics.getAscent());
00237            orgy += metrics.getHeight();
00238        }
00239     }
00240 
00241     private Dimension textExtent() {
00242         if (!fSizeIsDirty)
00243             return new Dimension(fWidth, fHeight);
00244         FontMetrics metrics =
00245            Toolkit.getDefaultToolkit().getFontMetrics(fFont);
00246        fWidth = 0;
00247        fHeight = 0;
00248        StringTokenizer st = new StringTokenizer(fText, "\n");
00249        while (st.hasMoreTokens()) {
00250            String t = st.nextToken();
00251            fHeight += metrics.getHeight();
00252            int w = metrics.stringWidth(t);
00253            if (w > fWidth)
00254               fWidth = w;
00255        }
00256 
00257         fSizeIsDirty = false;
00258         return new Dimension(fWidth, fHeight);
00259     }
00260 
00261     private void markDirty() {
00262         fSizeIsDirty = true;
00263     }
00264 
00265     private Dimension getRowsAndColumns(String text) {
00266        int rows = 0;
00267        int cols = 0;
00268        StringTokenizer st = new StringTokenizer(fText, "\n");
00269        while (st.hasMoreTokens()) {
00270            String t = st.nextToken();
00271            if (t.length() > cols)
00272               cols = t.length();
00273            rows++;
00274        }
00275        return new Dimension(cols, rows);
00276     }
00277 
00281     public int overlayColumns() {
00282        Dimension d = getRowsAndColumns(getText());
00283         return d.width < 20 ? 20 : d.width;
00284     }
00285 
00289     public int overlayRows() {
00290        Dimension d = getRowsAndColumns(getText());
00291         return d.height < 5 ? 5 : d.height;
00292     }
00293 
00294     public Vector handles() {
00295         Vector handles = new Vector();
00296         handles.addElement(new NullHandle(this, RelativeLocator.northWest()));
00297         handles.addElement(new NullHandle(this, RelativeLocator.northEast()));
00298         handles.addElement(new NullHandle(this, RelativeLocator.southEast()));
00299         handles.addElement(new FontSizeHandle(this, RelativeLocator.southWest()));
00300         return handles;
00301     }
00302 
00303     public void write(StorableOutput dw) {
00304         super.write(dw);
00305         dw.writeInt(fOriginX);
00306         dw.writeInt(fOriginY);
00307         dw.writeString(fText);
00308         dw.writeString(fFont.getName());
00309         dw.writeInt(fFont.getStyle());
00310         dw.writeInt(fFont.getSize());
00311         dw.writeBoolean(fIsReadOnly);
00312         dw.writeStorable(fObservedFigure);
00313         dw.writeStorable(fLocator);
00314     }
00315 
00316     public void read(StorableInput dr) throws IOException {
00317         super.read(dr);
00318         markDirty();
00319         fOriginX = dr.readInt();
00320         fOriginY = dr.readInt();
00321         fText = dr.readString();
00322         fFont = new Font(dr.readString(), dr.readInt(), dr.readInt());
00323         fIsReadOnly = dr.readBoolean();
00324 
00325         fObservedFigure = (Figure)dr.readStorable();
00326         if (fObservedFigure != null) {
00327             setAttribute("observed.figure", fObservedFigure);
00328             fObservedFigure.addFigureChangeListener(this);
00329         }
00330         fLocator = (OffsetLocator)dr.readStorable();
00331     }
00332 
00333     private void readObject(ObjectInputStream s)
00334         throws ClassNotFoundException, IOException {
00335 
00336         s.defaultReadObject();
00337 
00338         if (fObservedFigure != null)
00339             fObservedFigure.addFigureChangeListener(this);
00340         markDirty();
00341     }
00342 
00343     public void connect(Figure figure) {
00344         if (fObservedFigure != null)
00345             fObservedFigure.removeFigureChangeListener(this);
00346 
00347         fObservedFigure = figure;
00348         fLocator = new OffsetLocator(figure.connectedTextLocator(this));
00349         fObservedFigure.addFigureChangeListener(this);
00350         setAttribute("observed.figure", fObservedFigure);
00351         updateLocation();
00352     }
00353 
00354     public void figureChanged(FigureChangeEvent e) {
00355         updateLocation();
00356     }
00357 
00358     public void figureRemoved(FigureChangeEvent e) {
00359         if (listener() != null)
00360             listener().figureRequestRemove(new FigureChangeEvent(this));
00361     }
00362 
00363     public void figureRequestRemove(FigureChangeEvent e) {}
00364     public void figureInvalidated(FigureChangeEvent e) {}
00365     public void figureRequestUpdate(FigureChangeEvent e) {}
00366 
00371     protected void updateLocation() {
00372         if (fLocator != null) {
00373             Point p = fLocator.locate(fObservedFigure);
00374             p.x -= size().width/2 + fOriginX;
00375             p.y -= size().height/2 + fOriginY;
00376 
00377             if (p.x != 0 || p.y != 0) {
00378                 willChange();
00379                 basicMoveBy(p.x, p.y);
00380                 changed();
00381             }
00382         }
00383     }
00384 
00385     public void release() {
00386         super.release();
00387         if (fObservedFigure != null)
00388             fObservedFigure.removeFigureChangeListener(this);
00389     }
00390 
00394     public void disconnect() {
00395         fObservedFigure.removeFigureChangeListener(this);
00396         fObservedFigure = null;
00397         fLocator = null;
00398         setAttribute("observed.figure", null);
00399     }
00400 
00401 
00405     static public Font createCurrentFont() {
00406         return new Font(fgCurrentFontName, fgCurrentFontStyle, fgCurrentFontSize);
00407     }
00408 
00412     static public void setCurrentFontName(String name) {
00413         fgCurrentFontName = name;
00414     }
00415 
00419     static public void setCurrentFontSize(int size) {
00420         fgCurrentFontSize = size;
00421     }
00422 
00426     static public void setCurrentFontStyle(int style) {
00427         fgCurrentFontStyle = style;
00428     }
00429 }