Back to index

moin  1.9.0~rc2
PolyLineFigure.java
Go to the documentation of this file.
00001 /*
00002  * @(#)PolyLineFigure.java 5.1
00003  *
00004  */
00005 
00006 package CH.ifa.draw.figures;
00007 
00008 import java.awt.*;
00009 import java.util.*;
00010 import java.io.*;
00011 import java.net.*;
00012 import CH.ifa.draw.framework.*;
00013 import CH.ifa.draw.standard.*;
00014 import CH.ifa.draw.util.*;
00015 
00022 public  class PolyLineFigure extends AbstractFigure {
00023 
00024     public final static int ARROW_TIP_NONE  = 0;
00025     public final static int ARROW_TIP_START = 1;
00026     public final static int ARROW_TIP_END   = 2;
00027     public final static int ARROW_TIP_BOTH  = 3;
00028     
00029     protected Vector              fPoints;
00030     protected LineDecoration      fStartDecoration = null;
00031     protected LineDecoration      fEndDecoration = null;
00032     protected Color               fFrameColor = Color.black;
00033     
00034     /*
00035      * Serialization support.
00036      */
00037     private static final long serialVersionUID = -7951352179906577773L;
00038     private int polyLineFigureSerializedDataVersion = 1;
00039     
00040     public PolyLineFigure() {
00041         fPoints = new Vector(4);
00042     }
00043     
00044     public PolyLineFigure(int size) {
00045         fPoints = new Vector(size);
00046     }
00047     
00048     public PolyLineFigure(int x, int y) {
00049        fPoints = new Vector();
00050        fPoints.addElement(new Point(x, y));
00051     }
00052     
00053     public Rectangle displayBox() {
00054         Enumeration k = points();
00055         Rectangle r = new Rectangle((Point) k.nextElement());
00056        
00057         while (k.hasMoreElements())
00058             r.add((Point) k.nextElement());
00059        
00060         return r;
00061     }
00062     
00063     public boolean isEmpty() {
00064         return (size().width < 3) && (size().height < 3);
00065     }
00066     
00067     public Vector handles() {
00068         Vector handles = new Vector(fPoints.size());
00069         for (int i = 0; i < fPoints.size(); i++)
00070             handles.addElement(new PolyLineHandle(this, locator(i), i));
00071         return handles;
00072     }
00073     
00074     public void basicDisplayBox(Point origin, Point corner) {
00075     }
00076     
00080     public void addPoint(int x, int y) {
00081         fPoints.addElement(new Point(x, y));
00082         changed();
00083     }
00084     
00085     public Enumeration points() {
00086         return fPoints.elements();
00087     }
00088     
00089     public int pointCount() {
00090         return fPoints.size();
00091     }
00092 
00093     protected void basicMoveBy(int dx, int dy) {
00094         Enumeration k = fPoints.elements();
00095         while (k.hasMoreElements())
00096             ((Point) k.nextElement()).translate(dx, dy);
00097     }
00098 
00102     public void setPointAt(Point p, int i) {
00103         willChange();
00104         fPoints.setElementAt(p, i);
00105         changed();
00106     }
00107 
00111     public void insertPointAt(Point p, int i) {
00112         fPoints.insertElementAt(p, i);
00113         changed();
00114     }
00115 
00116     public void removePointAt(int i) {
00117         willChange();
00118         fPoints.removeElementAt(i);
00119         changed();
00120     }
00121 
00126     public int splitSegment(int x, int y) {
00127         int i = findSegment(x, y);
00128         if (i != -1)
00129             insertPointAt(new Point(x, y), i+1);
00130         return i+1;
00131     }
00132 
00133     public Point pointAt(int i) {
00134         return (Point)fPoints.elementAt(i);
00135     }
00136 
00142     public boolean joinSegments(int x, int y) {
00143         for (int i= 1; i < fPoints.size()-1; i++) {
00144             Point p = pointAt(i);
00145             if (Geom.length(x, y, p.x, p.y) < 3) {
00146                 removePointAt(i);
00147                 return true;
00148             }
00149         }
00150         return false;
00151     }
00152 
00153     public Connector connectorAt(int x, int y) {
00154         return new PolyLineConnector(this);
00155     }
00156 
00160     public void setStartDecoration(LineDecoration l) {
00161         fStartDecoration = l;
00162     }
00163 
00167     public void setEndDecoration(LineDecoration l) {
00168         fEndDecoration = l;
00169     }
00170 
00171     public void draw(Graphics g, boolean showGuides) {
00172         g.setColor(getFrameColor());
00173         Point p1, p2;
00174         for (int i = 0; i < fPoints.size()-1; i++) {
00175             p1 = (Point) fPoints.elementAt(i);
00176             p2 = (Point) fPoints.elementAt(i+1);
00177             g.drawLine(p1.x, p1.y, p2.x, p2.y);
00178         }
00179         decorate(g);
00180        if (showGuides) {
00181            drawURL(g);
00182        }
00183     }
00184 
00185     private void drawURL(Graphics g) {
00186        String sensitive = (String)getAttribute("Sensitive");
00187        if (sensitive == null || sensitive.length() == 0)
00188            return;
00189        int i;
00190        if (fPoints.size() < 3)
00191            i = 0;
00192        else
00193            i =  fPoints.size() / 2 - 1;
00194        Point p1, p2;
00195 
00196        if ((fPoints.size() & 1) == 1) {
00197            p2 = p1 = (Point) fPoints.elementAt(i+1);
00198        } else {
00199            p1 = (Point) fPoints.elementAt(i);
00200            p2 = (Point) fPoints.elementAt(i+1);
00201        }
00202        g.setColor(Color.red);
00203        g.setFont(dialogFont);
00204        g.drawString("url=" + sensitive, (p1.x + p2.x) / 2,
00205                    (p1.y + p2.y) / 2);
00206     }
00207 
00208     public boolean containsPoint(int x, int y) {
00209         Rectangle bounds = displayBox();
00210         bounds.grow(4,4);
00211         if (!bounds.contains(x, y))
00212             return false;
00213 
00214         Point p1, p2;
00215         for (int i = 0; i < fPoints.size()-1; i++) {
00216             p1 = (Point) fPoints.elementAt(i);
00217             p2 = (Point) fPoints.elementAt(i+1);
00218             if (Geom.lineContainsPoint(p1.x, p1.y, p2.x, p2.y, x, y))
00219                 return true;
00220         }
00221         return false;
00222     }
00223 
00229     public int findSegment(int x, int y) {
00230         Point p1, p2;
00231         for (int i = 0; i < fPoints.size()-1; i++) {
00232             p1 = (Point) fPoints.elementAt(i);
00233             p2 = (Point) fPoints.elementAt(i+1);
00234             if (Geom.lineContainsPoint(p1.x, p1.y, p2.x, p2.y, x, y))
00235                 return i;
00236         }
00237         return -1;
00238     }
00239 
00240     private void decorate(Graphics g) {
00241         if (fStartDecoration != null) {
00242             Point p1 = (Point)fPoints.elementAt(0);
00243             Point p2 = (Point)fPoints.elementAt(1);
00244             fStartDecoration.draw(g, p1.x, p1.y, p2.x, p2.y);
00245         }
00246         if (fEndDecoration != null) {
00247             Point p3 = (Point)fPoints.elementAt(fPoints.size()-2);
00248             Point p4 = (Point)fPoints.elementAt(fPoints.size()-1);
00249             fEndDecoration.draw(g, p4.x, p4.y, p3.x, p3.y);
00250         }
00251     }
00252 
00258     public Object getAttribute(String name) {
00259         if (name.equals("FrameColor")) {
00260             return getFrameColor();
00261         } else if (name.equals("ArrowMode")) {
00262             int value = 0;
00263             if (fStartDecoration != null)
00264                 value |= ARROW_TIP_START;
00265             if (fEndDecoration != null)
00266                 value |= ARROW_TIP_END;
00267             return new Integer(value);
00268        }
00269         return super.getAttribute(name);
00270     }
00271 
00277     public void setAttribute(String name, Object value) {
00278         if (name.equals("FrameColor")) {
00279             setFrameColor((Color)value);
00280             changed();
00281         } else if (name.equals("ArrowMode")) {
00282             Integer intObj = (Integer) value;
00283             if (intObj != null) {
00284                 int decoration = intObj.intValue();
00285                 if ((decoration & ARROW_TIP_START) != 0)
00286                     fStartDecoration = new ArrowTip();
00287                 else
00288                     fStartDecoration = null;
00289                 if ((decoration & ARROW_TIP_END) != 0)
00290                     fEndDecoration = new ArrowTip();
00291                 else
00292                     fEndDecoration = null;
00293             }
00294             changed();
00295        } else {
00296             super.setAttribute(name, value);
00297            changed();
00298        }
00299     }
00300 
00301     public void write(StorableOutput dw) {
00302         super.write(dw);
00303         dw.writeInt(fPoints.size());
00304         Enumeration k = fPoints.elements();
00305         while (k.hasMoreElements()) {
00306             Point p = (Point) k.nextElement();
00307             dw.writeInt(p.x);
00308             dw.writeInt(p.y);
00309         }
00310         dw.writeStorable(fStartDecoration);
00311         dw.writeStorable(fEndDecoration);
00312         dw.writeColor(fFrameColor);
00313     }
00314 
00315     public String getMap() {
00316        String sensitive = (String)getAttribute("Sensitive");
00317        if (sensitive == null || sensitive.length() == 0)
00318            return "";
00319        try {
00320               sensitive = URLDecoder.decode(sensitive);
00321        } catch (Exception e) {}
00322        Enumeration k = fPoints.elements();
00323        boolean first  = true;
00324        String forwards = "", backwards = "";
00325         for (int i = 1; i < fPoints.size(); i++) {
00326             Point p1 = (Point)fPoints.elementAt(i-1);
00327             Point p2 = (Point)fPoints.elementAt(i);
00328            double l = Math.sqrt((p2.x-p1.x) * (p2.x-p1.x) +
00329                              (p2.y-p1.y) * (p2.y-p1.y));
00330            int x = (int)(4 * (p2.y-p1.y) / l);
00331            int y = (int)(4 * (p2.x-p1.x) / l);
00332            if (!first) {
00333               forwards += ",";
00334               backwards = "," + backwards;
00335            }
00336            first = false;
00337            forwards += (p1.x + x) + "," + (p1.y + y) + "," +
00338               (p2.x + x) + "," + (p2.y + y);
00339            backwards = (p2.x - x) + "," + (p2.y - y) + "," +
00340               (p1.x - x) + "," + (p1.y - y) + backwards;
00341         }
00342        return "<area shape=\"poly\" coords=\"" +
00343            forwards + "," + backwards + "\" href=\"" +
00344            sensitive + "\" />\n";
00345     }
00346 
00347     public void read(StorableInput dr) throws IOException {
00348        // test for the next token being a number to allow us to
00349        // skip attribute reading which. Old-format files don't
00350        // have attributes on connections.
00351        super.read(dr);
00352         int size = dr.readInt();
00353        if (size == -1) {
00354            // Temp for files created during devt. Remove when we're sure
00355            // they are all gone
00356            String s = dr.readString();
00357            setAttribute("Sensitive", s);
00358            size = dr.readInt();
00359        }
00360         fPoints = new Vector(size);
00361         for (int i=0; i<size; i++) {
00362             int x = dr.readInt();
00363             int y = dr.readInt();
00364             fPoints.addElement(new Point(x,y));
00365         }
00366         fStartDecoration = (LineDecoration)dr.readStorable();
00367         fEndDecoration = (LineDecoration)dr.readStorable();
00368         fFrameColor = dr.readColor();
00369     }
00370 
00374     public static Locator locator(int pointIndex) {
00375         return new PolyLineLocator(pointIndex);
00376     }
00377 
00378     protected Color getFrameColor() {
00379         return fFrameColor;
00380     }
00381 
00382     protected void setFrameColor(Color c) {
00383         fFrameColor = c;
00384     }
00385 }