/*
* 05/05/2002 - 22:26:20
*
* ZLien - Copyright (C) 2002 Dreux Loic dreuxl@free.fr
*
* Modifications :
* ---------------
* Auteur : Bruno Dabo <bruno.dabo@lywoonsoftware.com>
* Date : 2009 jan 22
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.analyse.core.gui.zgraph;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import org.analyse.core.util.Constantes;
public abstract class ZLien
{
/** premier <code>ZElement</code> à lier */
protected ZElement elem1;
/** deuxième <code>ZElement</code> à lier */
protected ZElement elem2;
protected ZElement elem3; // bdabo janv 2009
/** Position x1 */
protected int x1;
/** Position x2 */
protected int x2;
/** Position y1 */
protected int y1;
/** Position y2 */
protected int y2;
/**
* Définie un <code>ZLien</code> avec les deux <code>ZElement</code>
* qu'il lie
*
* @param elem1
* premier <code>ZElement</code> à lier
* @param elem2
* deuxième <code>ZElement</code> à lier
* @param elem3
* troisieme <code>ZElement</code> à lier
*/
public ZLien(ZElement elem1, ZElement elem2, ZElement elem3)
{
this.elem1 = elem1;
this.elem2 = elem2;
this.elem3 = elem3;
}
/**
* Définie un <code> ZLien </code> sans argument. Ce lien est destiné à être
* lié par la suite dans le <code> ZGraphique </code>
*/
public ZLien()
{
this(null, null, null);
}
/** Change l'élément 1, 2 ou 3 */
public void setElement(ZElement elem, String index)
{
if (index == Constantes.MCDENTITE1 )
this.elem1 = elem;
else if (index == Constantes.MCDENTITE2 )
this.elem2 = elem;
else if (index == Constantes.MCDASSOCIATION)
this.elem3 = elem;
else
throw new IllegalArgumentException("");
}
/** Retourne l'élément 1, 2 ou 3 */
public ZElement getElement(String index)
{
if (index == Constantes.MCDENTITE1 )
return elem1;
else if (index == Constantes.MCDENTITE2 )
return elem2;
else if (index == Constantes.MCDASSOCIATION )
return elem3;
throw new IllegalArgumentException("");
}
/**
* Cette méthode est appelée avant la suppression du lien.
*/
public abstract void clearElement();
/**
* Redessine le composant dans un <code>ZGraphique</code> Attention : il
* est important d'appeler une méthode de calcul des coordonnées des points :
* soit calculPositionsDefaut() ou calculPositionsCentre().
*
* @param g
* Graphics du <code>ZGraphique</code>
*/
public abstract void paint(Graphics g);
/**
* <br>
* Inverse les deux Elements : elem1 devient elem2 elem2 devient elem1</br>
*/
public void inverseZElements()
{
ZElement elem = elem1;
elem1 = elem2;
elem2 = elem;
}
/**
* Dessine le focus du composant s'il est sélectionné
*/
public void paintFocus(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
Rectangle2D r;
r = new Rectangle2D.Double(x1 - 1, y1 - 1, 4, 4);
g2d.setColor(Color.black);
g2d.fill(r);
r = new Rectangle2D.Double(x2 - 2, y2 - 1, 4, 4);
g2d.setColor(Color.black);
g2d.fill(r);
}
/** Calcul des coordonnées des deux extrémités par défaut */
protected void updateDefaultLocation()
{
//Récupération des centres
int centrex1 = (elem1.getX() + elem1.getWidth() / 2);
int centrey1 = (elem1.getY() + elem1.getHeight() / 2);
int centrex2 = (elem2.getX() + elem2.getWidth() / 2);
int centrey2 = (elem2.getY() + elem2.getHeight() / 2);
int hauteur = centrex2 - centrex1;
int largeur = centrey2 - centrey1;
if (Math.abs(hauteur) > Math.abs(largeur)) {
x1 = hauteur > 0 ? elem1.getX() + elem1.getWidth() : elem1.getX();
y1 = elem1.getY() + elem1.getHeight() / 2;
x2 = hauteur < 0 ? elem2.getX() + elem2.getWidth() : elem2.getX();
y2 = elem2.getY() + elem2.getHeight() / 2;
} else {
x1 = elem1.getX() + elem1.getWidth() / 2;
y1 = largeur > 0 ? elem1.getY() + elem1.getHeight() : elem1.getY();
x2 = elem2.getX() + elem2.getWidth() / 2;
y2 = largeur < 0 ? elem2.getY() + elem2.getHeight() : elem2.getY();
}
}
/** Calcul des coordonnées par rapport au centre */
public void updateLocation()
{
double theta, l1, l2, l3, diagonale;
double thetas[] = new double[4];
int pointx, pointy;
//Récupération des centres
int centrex1 = (elem1.getX() + elem1.getWidth() / 2);
int centrey1 = (elem1.getY() + elem1.getHeight() / 2);
int centrex2 = (elem2.getX() + elem2.getWidth() / 2);
int centrey2 = (elem2.getY() + elem2.getHeight() / 2);
// premier rectangle
diagonale = Math.sqrt((elem1.getWidth()) * (elem1.getWidth())
+ (elem1.getHeight()) * (elem1.getHeight()));
thetas[0] = Math.acos(elem1.getWidth() / diagonale);
thetas[1] = Math.acos(-elem1.getWidth() / diagonale);
thetas[2] = 2 * Math.PI - thetas[1];
thetas[3] = 2 * Math.PI - thetas[0];
l1 = centrex2 - centrex1;
l2 = centrey2 - centrey1;
l3 = Math.sqrt((centrex1 - centrex2) * (centrex1 - centrex2)
+ (centrey1 - centrey2) * (centrey1 - centrey2));
theta = Math.acos(l1 / l3);
if (centrey1 > centrey2)
theta = 2 * Math.PI - theta;
if (theta < thetas[0] || theta >= thetas[3]) {
y1 = (int) (elem1.getY() + elem1.getHeight() / 2 + (((elem1
.getWidth() / 2) * l2) / l1));
x1 = elem1.getX() + elem1.getWidth();
} else if (theta >= thetas[1] && theta < thetas[2]) {
y1 = (int) (elem1.getY() + elem1.getHeight() / 2 - (((elem1
.getWidth() / 2) * l2) / l1));
x1 = elem1.getX();
} else if (theta >= thetas[0] && theta < thetas[1]) {
y1 = elem1.getY() + elem1.getHeight();
x1 = (int) (elem1.getX() + elem1.getWidth() / 2 + (((elem1
.getHeight() / 2) * l1) / l2));
} else {
y1 = elem1.getY();
x1 = (int) (elem1.getX() + elem1.getWidth() / 2 - (((elem1
.getHeight() / 2) * l1) / l2));
}
// deuxième rectangle
theta = 2 * Math.PI - theta;
diagonale = Math.sqrt((elem2.getWidth()) * (elem2.getWidth())
+ (elem2.getHeight()) * (elem2.getHeight()));
thetas[0] = Math.acos(elem2.getWidth() / diagonale);
thetas[1] = Math.acos(-elem2.getWidth() / diagonale);
thetas[2] = 2 * Math.PI - thetas[1];
thetas[3] = 2 * Math.PI - thetas[0];
if (theta < thetas[0] || theta >= thetas[3]) {
y2 = (int) (elem2.getY() + elem2.getHeight() / 2 - (((elem2
.getWidth() / 2) * l2) / l1));
x2 = elem2.getX();
} else if (theta >= thetas[1] && theta < thetas[2]) {
y2 = (int) (elem2.getY() + elem2.getHeight() / 2 + (((elem2
.getWidth() / 2) * l2) / l1));
x2 = elem2.getX() + elem2.getWidth();
} else if (theta >= thetas[0] && theta < thetas[1]) {
y2 = elem2.getY() + elem2.getHeight();
x2 = (int) (elem2.getX() + elem2.getWidth() / 2 + (((elem2
.getHeight() / 2) * l1) / l2));
} else {
y2 = elem2.getY();
x2 = (int) (elem2.getX() + elem2.getWidth() / 2 - (((elem2
.getHeight() / 2) * l1) / l2));
}
}
public int getX1()
{
return x1;
}
public int getY1()
{
return y1;
}
public int getX2()
{
return x2;
}
public int getY2()
{
return y2;
}
public boolean isSelected(int mousex, int mousey)
{
double a, b, c, h, g;
a = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
b = Math.sqrt((x1 - mousex) * (x1 - mousex) + (y1 - mousey)
* (y1 - mousey));
c = Math.sqrt((mousex - x2) * (mousex - x2) + (mousey - y2)
* (mousey - y2));
h = a / 2 - (b * b) / (2 * a) + c * c / (2 * a);
g = Math.sqrt(c * c - h * h);
return g < 10
&& (mousex > x1 - 10 && mousex < x2 + 10 || mousex < x1 + 10
&& mousex > x2 - 10)
&& (mousey > y1 - 10 && mousey < y2 + 10 || mousey < y1 + 10
&& mousey > y2 - 10);
}
public void notifyZLien()
{
elem1.changementLien();
elem1.notifyZElement();
}
public String toString()
{
return "ZLien, " + info();
}
public String info()
{
return "Element 1 : {" + elem1 + "}, Element 2 : {" + elem2
+ "}, Element 3 : {" + elem3 + "}, Point1(" + x1 + ";" + y1 + "), Point2(" + x2 + ";" + y2
+ ")";
}
}