View Javadoc

1   /*
2    *  nextobjects Copyright (C) 2001-2005 Emmanuel Florent
3    *  This program is free software; you can redistribute it and/or modify
4    *  it under the terms of the GNU General Public License as published by the
5    *  Free Software Foundation; either version 2 of the License, or (at your
6    *  option) any later version.
7    *  This program is distributed in the hope that it will
8    *  be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
9    *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10   *  PURPOSE. See the GNU General Public License for more details.
11   *  You should have received a copy of the GNU General Public License along
12   *  with this program; if not, write to the Free Software Foundation, Inc., 59
13   *  Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14   */
15  package org.devaki.nextobjects.workspace.models.graphics;
16  import java.io.Serializable;
17  import java.awt.Graphics;
18  import java.awt.Font;
19  import java.awt.Point;
20  import javax.swing.UIManager;
21  import java.awt.Polygon;
22  import org.devaki.nextobjects.util.NOGraphicsUtil;
23  import org.devaki.nextobjects.workspace.models.objects.BaseLine;
24  import org.devaki.nextobjects.workspace.models.objects.Constraint;
25  import org.devaki.nextobjects.workspace.models.columns.Column;
26  /***
27   *  Draw a Constraint in a PhysicalView of a PhysicalModel
28   *
29   * @author     <a href="mailto:eflorent@devaki.org">Emmanuel Florent</a>
30   * @created    December 22, 2003
31   */
32  public class ConstraintView extends LineView implements Serializable
33  {
34      /***  Arrowhead sharpness */
35      private double fTheta = Math.toRadians(20);
36      /***  Arrowhead length */
37      private final int fSize = 15;
38      /***
39       *  Construct a new 'ConstraintView' object
40       *
41       * @param  pConstraint  the contextual <code>Constraint</code>
42       */
43      public ConstraintView(final Constraint pConstraint)
44      {
45          super(pConstraint);
46          selectionPoints[0] =
47              ((BaseLine) this.getBaseObject())
48                  .getParentClass()
49                  .getObjectView()
50                  .getSelectionPoint(0);
51          selectionPoints[1] =
52              ((BaseLine) this.getBaseObject())
53                  .getChildClass()
54                  .getObjectView()
55                  .getSelectionPoint(0);
56          computeBestPoints();
57      }
58      /***
59       *  Paint
60       *
61       * @param  g  the graphics context
62       */
63      public final void paint(final Graphics g)
64      {
65          Point p0 =
66              ((PhysicalView) myObject.getMyModel().getPanel())
67                  .getRectangle()
68                  .getLocation();
69          Point p1 = selectionPoints[1].getPoint();
70          p1.translate(-p0.x, -p0.y);
71          Point p2 = selectionPoints[0].getPoint();
72          p2.translate(-p0.x, -p0.y);
73          int x1 = (int) p1.getX();
74          int y1 = (int) p1.getY();
75          int x2 = (int) p2.getX();
76          int y2 = (int) p2.getY();
77          // Set color from style
78          g.setColor(this.myStyle.getLineColor());
79          if (!((Constraint) this.getBaseObject()).isSelfRef())
80          {
81              g.drawLine(x1, y1, x2, y2);
82          }
83          else
84          {
85              Point p = getCtrlPoint(p2);
86              g.drawLine(x1, y1, p.x, p.y);
87              g.drawLine(x2, y2, p.x, p.y);
88              //used to write smre else ..
89              x1 = p.x;
90              y1 = p.y;
91          }
92          g.setFont(
93              new Font(
94                  ((Font) UIManager.get("Label.font")).getName(),
95                  Font.BOLD,
96                  ((Font) UIManager.get("Label.font")).getSize()));
97          // calculate points for arrowhead
98          double angle = Math.atan2(y1 - y2, x1 - x2) + Math.PI;
99          int x3 = (int) (x1 + Math.cos(angle - fTheta) * fSize);
100         int y3 = (int) (y1 + Math.sin(angle - fTheta) * fSize);
101         if (((Column) ((Constraint) this.myObject)
102             .getLocalColumns()
103             .iterator()
104             .next())
105             .isRequired())
106         {
107             g.drawString("1", x3, y3);
108         }
109         else
110         {
111             g.drawString("0 ... 1", x3, y3);
112         }
113         angle = Math.atan2(y2 - y1, x2 - x1) + Math.PI;
114         int x4 = (int) (x2 + Math.cos(angle - fTheta) * fSize);
115         int y4 = (int) (y2 + Math.sin(angle - fTheta) * fSize);
116         x3 = (int) (x2 + Math.cos(angle + fTheta) * fSize);
117         y3 = (int) (y2 + Math.sin(angle + fTheta) * fSize);
118         g.drawLine(x3, y3, x2, y2);
119         g.drawLine(x4, y4, x2, y2);
120         x3 = (int) (x2 + Math.cos(angle + fTheta) * fSize * 1.1);
121         y3 = (int) (y2 + Math.sin(angle + fTheta) * fSize * 1.1);
122         g.drawString("*", x3, y3);
123     }
124     /***
125      *  Gets the ctrlPoint attribute of the ConstraintView object
126      *
127      * @param  p  Description of the Parameter
128      * @return    The ctrlPoint value
129      */
130     public final Point getCtrlPoint(final Point p)
131     {
132         int x = p.x;
133         int y = p.y;
134         int location = SelectionPoint.NORTH;
135         SelectionPoint[] pArray =
136             ((Constraint) myObject)
137                 .getParentClass()
138                 .getObjectView()
139                 .getSelectionPoints();
140         for (int i = 0; i < pArray.length; i++)
141         {
142             if (pArray[i].getPoint().x == selectionPoints[0].getPoint().x
143                 && pArray[i].getPoint().y == selectionPoints[0].getPoint().y)
144             {
145                 location = i;
146             }
147         }
148         int r = 30;
149         switch (location)
150         {
151             case 2 :
152                 // SelectionPoint.NORTH_WEST :
153                 x = x - r;
154                 y = y - r;
155                 break;
156             case 6 :
157                 //SelectionPoint.WEST :
158                 x = x - r;
159                 break;
160             case 0 :
161                 //SOUTH_WEST :
162                 x = x - r;
163                 y = y + r;
164                 break;
165             case 5 :
166                 //SOUTH:
167                 x = x + r;
168                 y = y + r;
169                 break;
170             case 1 :
171                 //SOUTH_EAST :
172                 //nothing to do
173                 x = x + r;
174                 y = y + r;
175                 break;
176             case 7 :
177                 //EAST :
178                 x = x + r;
179                 break;
180             case 3 :
181                 //NORTH_EAST :
182                 y = y - r;
183                 y = y - r;
184                 break;
185             case 4 :
186                 //NORTH
187             default :
188                 x = x - r;
189                 y = y - r;
190                 break;
191         }
192         return new Point(x, y);
193     }
194     /***  Reset the selection point. */
195     public void resetSelectionPoint()
196     {
197     }
198     /***
199      *  Return the surface on which the user can click to select the object
200      *
201      * @return    the surface as polygon/shape
202      */
203     public final Polygon getSurface()
204     {
205         int delta = 30;
206         Point ctrlPoint =
207             NOGraphicsUtil.getMiddle(
208                 selectionPoints[0].getPoint(),
209                 selectionPoints[1].getPoint());
210         //selfRef or not ..
211         if (((Constraint) this.getBaseObject()).isSelfRef())
212         {
213             ctrlPoint = getCtrlPoint(selectionPoints[0].getPoint());
214         }
215         int tmpX1 = (int) ctrlPoint.getX();
216         int tmpY1 = (int) ctrlPoint.getY();
217         int[] xi = {// +-5 is a seed of noise to avoid having
218             // a line when two points are same. Doing like this we have a
219             //parralelogram even if two points ares the same ...
220             (int) selectionPoints[0].getPoint().x - 5,
221                 tmpX1 - delta,
222                 (int) selectionPoints[1].getPoint().x + 5,
223                 tmpX1 + delta,
224                 selectionPoints[0].getPoint().x - 5 };
225         int[] yi =
226             {
227                 selectionPoints[0].getPoint().y,
228                 tmpY1 - delta,
229                 selectionPoints[1].getPoint().y,
230                 tmpY1 + delta,
231                 selectionPoints[1].getPoint().y };
232         return new Polygon(xi, yi, 4);
233     }
234 }