001package horstmann.ch08_umleditor; 002import java.awt.geom.Point2D; 003import java.awt.geom.Rectangle2D; 004import java.util.ArrayList; 005 006/** 007 A style for a segmented line that indicates the number 008 and sequence of bends. 009 */ 010public enum BentStyle 011{ 012 STRAIGHT, HV, VH, HVH, VHV; 013 014 /** 015 Gets the points at which a line joining two rectangles 016 is bent according to this bent style. 017 @param start the starting rectangle 018 @param end the ending rectangle 019 @return an array list of points at which to bend the 020 segmented line joining the two rectangles 021 */ 022 public ArrayList<Point2D> getPath(Rectangle2D start, Rectangle2D end) 023 { 024 ArrayList<Point2D> r = getPath(this, start, end); 025 if (r != null) return r; 026 027 if (this == HVH) r = getPath(VHV, start, end); 028 else if (this == VHV) r = getPath(HVH, start, end); 029 else if (this == HV) r = getPath(VH, start, end); 030 else if (this == VH) r = getPath(HV, start, end); 031 if (r != null) return r; 032 033 return getPath(STRAIGHT, start, end); 034 } 035 036 /** 037 Gets the four connecting points at which a bent line 038 connects to a rectangle. 039 */ 040 private static Point2D[] connectionPoints(Rectangle2D r) 041 { 042 Point2D[] a = new Point2D[4]; 043 a[0] = new Point2D.Double(r.getX(), r.getCenterY()); 044 a[1] = new Point2D.Double(r.getMaxX(), r.getCenterY()); 045 a[2] = new Point2D.Double(r.getCenterX(), r.getY()); 046 a[3] = new Point2D.Double(r.getCenterX(), r.getMaxY()); 047 return a; 048 } 049 050 /** 051 Gets the points at which a line joining two rectangles 052 is bent according to a bent style. 053 @return an array list of points at which to bend the 054 segmented line joining the two rectangles 055 */ 056 private static ArrayList<Point2D> getPath(BentStyle bent, 057 Rectangle2D s, Rectangle2D e) 058 { 059 ArrayList<Point2D> r = new ArrayList<Point2D>(); 060 if (bent == STRAIGHT) 061 { 062 Point2D[] a = connectionPoints(s); 063 Point2D[] b = connectionPoints(e); 064 Point2D p = a[0]; 065 Point2D q = b[0]; 066 double distance = p.distance(q); 067 //for (int i = 0; i < a.length; i++) 068 for (Point2D point1 : a) 069 //for (int j = 0; j < b.length; j++) 070 for (Point2D point2 : b) 071 { 072 double d = point1.distance(point2); 073 if (d < distance) 074 { 075 p = point1; q = point2; 076 distance = d; 077 } 078 } 079 r.add(p); 080 r.add(q); 081 } 082 else if (bent == HV) 083 { 084 double x1; 085 double x2 = e.getCenterX(); 086 double y1 = s.getCenterY(); 087 double y2; 088 if (x2 + MIN_SEGMENT <= s.getX()) 089 x1 = s.getX(); 090 else if (x2 - MIN_SEGMENT >= s.getMaxX()) 091 x1 = s.getMaxX(); 092 else return null; 093 if (y1 + MIN_SEGMENT <= e.getY()) 094 y2 = e.getY(); 095 else if (y1 - MIN_SEGMENT >= e.getMaxY()) 096 y2 = e.getMaxY(); 097 else return null; 098 r.add(new Point2D.Double(x1, y1)); 099 r.add(new Point2D.Double(x2, y1)); 100 r.add(new Point2D.Double(x2, y2)); 101 } 102 else if (bent == VH) 103 { 104 double x1 = s.getCenterX(); 105 double x2; 106 double y1; 107 double y2 = e.getCenterY(); 108 if (x1 + MIN_SEGMENT <= e.getX()) 109 x2 = e.getX(); 110 else if (x1 - MIN_SEGMENT >= e.getMaxX()) 111 x2 = e.getMaxX(); 112 else return null; 113 if (y2 + MIN_SEGMENT <= s.getY()) 114 y1 = s.getY(); 115 else if (y2 - MIN_SEGMENT >= s.getMaxY()) 116 y1 = s.getMaxY(); 117 else return null; 118 r.add(new Point2D.Double(x1, y1)); 119 r.add(new Point2D.Double(x1, y2)); 120 r.add(new Point2D.Double(x2, y2)); 121 } 122 else if (bent == HVH) 123 { 124 double x1; 125 double x2; 126 double y1 = s.getCenterY(); 127 double y2 = e.getCenterY(); 128 if (s.getMaxX() + 2 * MIN_SEGMENT <= e.getX()) 129 { 130 x1 = s.getMaxX(); 131 x2 = e.getX(); 132 } 133 else if (e.getMaxX() + 2 * MIN_SEGMENT <= s.getX()) 134 { 135 x1 = s.getX(); 136 x2 = e.getMaxX(); 137 } 138 else return null; 139 if (Math.abs(y1 - y2) <= MIN_SEGMENT) 140 { 141 r.add(new Point2D.Double(x1, (y1 + y2) / 2)); 142 r.add(new Point2D.Double(x2, (y1 + y2) / 2)); 143 } 144 else 145 { 146 r.add(new Point2D.Double(x1, y1)); 147 r.add(new Point2D.Double((x1 + x2) / 2, y1)); 148 r.add(new Point2D.Double((x1 + x2) / 2, y2)); 149 r.add(new Point2D.Double(x2, y2)); 150 } 151 } 152 else if (bent == VHV) 153 { 154 double x1 = s.getCenterX(); 155 double x2 = e.getCenterX(); 156 double y1; 157 double y2; 158 if (s.getMaxY() + 2 * MIN_SEGMENT <= e.getY()) 159 { 160 y1 = s.getMaxY(); 161 y2 = e.getY(); 162 } 163 else if (e.getMaxY() + 2 * MIN_SEGMENT <= s.getY()) 164 { 165 y1 = s.getY(); 166 y2 = e.getMaxY(); 167 168 } 169 else return null; 170 if (Math.abs(x1 - x2) <= MIN_SEGMENT) 171 { 172 r.add(new Point2D.Double((x1 + x2) / 2, y1)); 173 r.add(new Point2D.Double((x1 + x2) / 2, y2)); 174 } 175 else 176 { 177 r.add(new Point2D.Double(x1, y1)); 178 r.add(new Point2D.Double(x1, (y1 + y2) / 2)); 179 r.add(new Point2D.Double(x2, (y1 + y2) / 2)); 180 r.add(new Point2D.Double(x2, y2)); 181 } 182 } 183 else return null; 184 return r; 185 } 186 187 private static final int MIN_SEGMENT = 10; 188}