Package org.analyse.core.gui.zgraph

Source Code of org.analyse.core.gui.zgraph.ZGraphique

/*
* 05/02/2002 - 20:15:18
*
* ZGraphique -
* Copyright (C) 2002 Dreux Loic
* dreuxl@free.fr
*
*  Modifications
*  -------------
*  Date : 2009 janvier 22
*  @auteur : Bruno Dabo <bruno.dabo@lywoonsoftware.com>
*  @objet : enlever les limites sur les vecteurs
*  Date : 2009 mars 13
*  @auteur : Benjamin Gandon
*  @objet : ajouter la sélection multiple
*
* 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.AWTEvent;
import java.awt.AWTEventMulticaster;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import javax.swing.JComponent;

import org.analyse.core.util.Constantes;

/**
* ZGraphique est un composant permettant d'afficher des éléments graphiques, de
* les déplacer, de les lier. <br>
* <br>
* Il est conseiller d'utiliser ce composant dans un <code>JScrollPane<code>.
*
*<pre>
* Container c = getContentPane();
* c.setLayout(new BorderLayout());
* c.add(BorderLayout.CENTER, new JScrollPane(new ZGraphique()));
* </pre>
*/
public class ZGraphique extends JComponent implements MouseListener,
        MouseMotionListener, Observer
{
    /** Vecteur de <code>ZElement</code> */
    private List<ZElement> zelements = new ArrayList<ZElement>() ;

    /** Vecteur de <code>ZLien</code> */
    private List<ZLien> zliens = new ArrayList<ZLien>() ;

    /**
     * Cette variable sert pour le glisser-déposer. Lorsque l'on clic sur un
     * <code>ZElement</code> la variable est liée à ce <code>ZElement</code>
     * jusqu'à ce qu'on relache la souris
     */
    private ZElement elementPress = null;

    /**
     * Cette variable est liée vers un <code>ZElement</code> sur lequel on a
     * cliqué jusque l'on clique dans le vide ou sur un autre élément.
     */
    protected ZElement elementClic = null;
    /**
     * Cet {@link Set ensemble} contient les {@link ZElement}s de la sélection
     * courante.
     */
    protected Set<ZElement> selectionCourante = new LinkedHashSet<ZElement>();
    protected Set<ZElement> selectionTemporaire = new LinkedHashSet<ZElement>();

    /**
     * Cette variable est liée vers un <code>ZLien</code> sur lequel on a
     * cliqué jusque l'on clique dans le vide ou sur un autre élément.
     */
    protected ZLien lienClic = null;

    protected Point departCadreSelection = null;
    protected Point arriveeCadreSelection = null;

    /**
     * Cette variable est utilisée lors de la création d'un lien.
     */
    private ZLien lienTemp;

    /** Utilisé pour le déplacement des éléments. Contient la position relative par rapport à la souris. */
    private Map<ZElement, Point> positionsRelatives = new HashMap<ZElement, Point>();

    /** Possibilité d'intéragir sur le composant grâce à la souris. */
    private boolean enabled = true;

    /** Enclenche le mode 'création de lien' */
    private boolean creationLien = false;

    /** Indique si en mode 'création de lien', l'utilisateur a cliqué */
    private boolean creationLienClic = false;

    /** Gestion des événement */
    private ActionListener actionListener;

    /** Pour la position du lien */
    private int x1, y1, x2, y2;

    /**
     * Définie un <code>ZGraphique</code> avec les paramètres par défaut.
     */
    public ZGraphique()
    {
      setEnabled(false);
      addMouseListener(this)
        setSize(getPreferredSize());
        setBackground(Color.white);
    }
 
    /**
     * Active ou désactive l'intéraction de l'utilisateur avec le graphique.
     */
    public void setEnabled(boolean enabled)
    {
        this.enabled = enabled;
    }

  /**
     * Retourne la variable enabled.
     */
    public boolean getEnabled()
    {
        return enabled;
    }

    /**
     * Retourne le nombre de <code>ZElement</code>.
     */
    public int sizeElements()
    {
        return zelements.size();
    }

    /**
     * Retourne le nombre de <code>ZElement</code> actuellement sélectionnés.
     */
    public int sizeSelection()
    {
        return selectionCourante.size();
    }

    /**
     * Retourne le nombre de liens.
     */
    public int sizeLien()
    {
        return zliens.size();
    }

    /**
     * Retourne une Enumeration des <code>ZElement</code>.
     */
    public Iterator<ZElement> enumElements()
    {
        return zelements.iterator();
    }

    /**
     * Retourne une énumération des <code>ZLien</code>
     */
    public Iterator<ZLien> enumLiens()
    {
        return zliens.iterator();
    }

    /**
     * Ajoute un <code>ZElement</code> dans le composant.
     */
    public void addElement(ZElement element)
    {
        zelements.add(element);
        element.majObserver(this);
        repaint();
    }

    /**
     * Ajoute plusieurs <code>ZElement</code> dans le composant.
     */
    public void addElements(List<ZElement> elements)
    {
        Iterator<ZElement> e = elements.iterator();
        while (e.hasNext())
            addElement((ZElement) e.next());
    }

    /**
     * Supprime un <code>ZElement</code> du composant.
     */
    public void removeElement(ZElement element)
    {
        enleverFocus();

        Iterator<ZLien> e = zliens.iterator();
        List<ZLien> supp = new ArrayList<ZLien>();
        while (e.hasNext()) {
            ZLien l = (ZLien) (e.next());
            if (l.getElement(Constantes.MCDENTITE1).equals(element)
                    || l.getElement(Constantes.MCDENTITE2).equals(element))
                supp.add(l);
        }
        removeLiens(supp);
        zelements.remove(element);
        repaint();
    }

    /**
     * Ajoute un <code>ZLien</code> dans le composant.
     */
    public void addLien(ZLien lien)  {
     
        if (lien.getElement(Constantes.MCDENTITE1) != null && lien.getElement(Constantes.MCDENTITE2) != null
            && lien.getElement(Constantes.MCDENTITE1) != lien.getElement(Constantes.MCDENTITE2)
                && !zliens.contains(lien))
     
            zliens.add(lien);
        repaint();
    }

    /**
     * Ajoute plusieurs <code>ZLien</code> dans le composant.
     */
    public void addLiens(List<ZLien> liens)
    {
        Iterator<ZLien> e = liens.iterator();
        while (e.hasNext())
            addLien((ZLien) e.next());
    }

    /**
     * Supprime un <code>ZLien</code> du composant.
     */
    public void removeLien(ZLien lien)
    {
        enleverFocus();
        zliens.remove(lien);
        repaint();
    }

    /**
     * Supprime plusieurs <code>ZLien</code> du composant.
     */
    public void removeLiens(List<ZLien> supp)
    {
        for (Iterator<ZLien> e = supp.iterator(); e.hasNext();)
            removeLien((ZLien) e.next());
    }

    /**
     * Retourne un <code>ZLien</code> du composant.
     *
     * @param i
     *            index du lien à retourner
     */
    public ZLien getLien(int i)
    {
        return ((ZLien) (zliens.get(i)));
    }

    /**
     * Retourne le lien qui a le focus.
     */
    public ZLien getLienFocus()
    {
        return lienClic;
    }

    /**
     * Retourne une Enumeration des <code>ZLien</code>.
     */
    public Iterator<ZLien> elementsZLiens()
    {
        return zliens.iterator();
    }

    /**
     * Retourne un <code>ZElement</code> du composant.
     *
     * @param i
     *            index du composant à retourner
     */
    public ZElement getElement(int i)
    {
        return ((ZElement) (zelements.get(i)));
    }

    /**
     * Retourne le composant qui a le focus.
     */
    public ZElement getElementFocus()
    {
        return elementClic;
    }

    /**
     * Retourne une Enumeration des <code>ZElement</code>.
     */
    public Iterator<ZElement> elementsZElements()
    {
        return zelements.iterator();
    }

    /**
     * Retourne le premier {@link ZElement} se trouvant à la position x, y.
     */
    public ZElement chercheElement(int x, int y)
    {
        for (int i = zelements.size() - 1; i >= 0; i--)
            if (getElement(i).isSelected(x, y))
                return getElement(i);
        return null;
    }
    /**
     * Retourne le premier {@link ZLien} se trouvant à la position x, y.
     */
    public ZLien chercheLien(int x, int y)
    {
        for (int i = 0; i < zliens.size(); i++)
            if (getLien(i).isSelected(x, y))
                return getLien(i);
        return null;
    }
    /**
     * Retourne le premier composant se trouvant à la position x, y.
     */
    public Object getObjectFromLocation(int x, int y)
    {
        ZElement elem = chercheElement(x, y);
        if (elem != null)
            return elem;

        ZLien lien = chercheLien(x, y);
        if (lien != null)
            return lien;
        return null;
    }

    /**
     * Enlève le focus de tous les elements.
     */
    public void enleverFocus()
    {
        elementClic = null;
        selectionCourante.clear();
        selectionTemporaire.clear();
        lienClic = null;
    }

    /**
     * Enclenche le mode de "création de liens". Il est alors possible de liée
     * deux elements dans le graphe.
     */
    public void creerLien(ZLien lien)
    {
        enleverFocus();
        lienTemp = lien;
        lienTemp.setElement(null, Constantes.MCDENTITE1);
        lienTemp.setElement(null, Constantes.MCDENTITE2);
        if (zliens.contains(lien))
            removeLien(lien);
        creationLien = true;
        creationLienClic = false;
    }

    /**
     * Désenclenche le mode "création de liens".
     */
    public void annulerCreerLien()
    {
        enleverFocus();

        lienTemp = null;
        creationLien = false;
        creationLienClic = false;
    }

    /**
     * Cette méthode indique si l'on peut créer un lien entre deux éléments.
     */
    public boolean peutCreerLien(ZElement elem1, ZElement elem2)
    {
        ZLien lien;

        Iterator<ZLien> e = zliens.iterator();
        while (e.hasNext()) {
            lien = (ZLien) e.next();
            if (lien.getElement(Constantes.MCDENTITE1) == elem1
                    && lien.getElement(Constantes.MCDENTITE2) == elem2) {
                return false;
            }
        }
        return true;
    }

    public String infoZLiens()
    {
        String s = "{";
        for (Iterator<ZLien> e = elementsZLiens(); e.hasNext();) {
            ZLien lien = (ZLien) e.next();
            s += "\n" + lien;
        }
        return s + "\n}";
    }

    public void clearAll()
    {
        enleverFocus();
        zelements = new ArrayList<ZElement>();
        zliens = new ArrayList<ZLien>();
        repaint();
    }

    /**
     * Dessine le composant.
     */
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        g.setColor(getBackground());
        g.fillRect(0, 0, getWidth(), getHeight());

        Iterator<ZElement> e = zelements.iterator();
        while (e.hasNext())
            ((ZElement) (e.next())).paint(g);
       
        Iterator<ZLien> e1 = zliens.iterator();
        while (e1.hasNext())
            ((ZLien) (e1.next())).paint(g);

        for (ZElement elem : selectionCourante)
            elem.paintFocus(g);
        for (ZElement elem : selectionTemporaire)
            elem.paintFocus(g);
        if (lienClic != null)
            lienClic.paintFocus(g);

        if (departCadreSelection != null) {
            int x1 = (int)departCadreSelection.getX();
            int y1 = (int)departCadreSelection.getY();
            int x2 = (int)arriveeCadreSelection.getX();
            int y2 = (int)arriveeCadreSelection.getY();
            int w = x2 - x1;
            int h = y2 - y1;
            if (x2 < x1) {
                x1 = x2;
                w = -w;
            }
            if (y2 < y1) {
                y1 = y2;
                h = -h;
            }
            Graphics2D g2d = (Graphics2D) g;
            g2d.setColor(Color.green);
            g2d.draw(new Rectangle2D.Double(x1, y1, w, h));
        }

        if (creationLien && creationLienClic) {
            Graphics2D g2d = (Graphics2D) g;
            Rectangle2D r;
            g2d.setColor(Color.black);

            Line2D l = new Line2D.Double(x1, y1, x2, y2);
            g2d.draw(l);

            r = new Rectangle2D.Double(x1 - 1, y1 - 1, 4, 4);
            g2d.fill(r);

            r = new Rectangle2D.Double(x2 - 2, y2 - 1, 4, 4);
            g2d.fill(r);
        }
    }

    public Dimension getPreferredSize()
    {
        int x = 0, y = 0;
        for (int i = 0; i < zelements.size(); i++) {
            x = getElement(i).getX() + getElement(i).getWidth() > x ? getElement(
                    i).getX()
                    + getElement(i).getWidth()
                    : x;
            y = getElement(i).getY() + getElement(i).getHeight() > y ? getElement(
                    i).getY()
                    + getElement(i).getHeight()
                    : y;
        }
        return new Dimension(x + 30, y + 30);
    }

    public void update(Observable o, Object arg)
    {
        this.repaint();
    }

    public void addActionListener(ActionListener listener)
    {
        actionListener = AWTEventMulticaster.add(actionListener, listener);
        enableEvents(AWTEvent.MOUSE_EVENT_MASK);
    }

    public void removeActionListener(ActionListener listener)
    {
        actionListener = AWTEventMulticaster.remove(actionListener, listener);
    }

    public void mouseClicked(MouseEvent e)
    {
    }

    /* (non-Javadoc)
     * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
     */
    public void mousePressed(MouseEvent e)
    {   
      addMouseMotionListener(this);

        if (creationLien && enabled) {
            creationLienClic = true;
            int x = e.getX();
            int y = e.getY();

            x1 = e.getX();
            y1 = e.getY();

            x2 = e.getX();
            y2 = e.getY();

            ZElement departChoisi = chercheElement(x, y);
            if (departChoisi != null)
                lienTemp.setElement(departChoisi, Constantes.MCDENTITE1);

            repaint();

        } else if (enabled) {
            elementPress = null;
            elementClic = null;
            lienClic = null;

            int x = e.getX();
            int y = e.getY();

            ZElement nouvelleSelection = chercheElement(x, y);
            if (nouvelleSelection != null) {
                elementPress = nouvelleSelection;
                elementClic = nouvelleSelection;
                if ((e.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK) == 0
                        && !selectionCourante.contains(nouvelleSelection))
                    selectionCourante.clear();
                selectionCourante.add(nouvelleSelection);
                positionsRelatives.clear();
                for (ZElement elem : selectionCourante)
                    positionsRelatives.put(elem, new Point(x - elem.getX(), y - elem.getY()));
            }
            else {
                ZLien nouvelleSelectionLien = chercheLien(x, y);
                if (nouvelleSelectionLien != null) {
                    lienClic = nouvelleSelectionLien;
                    selectionCourante.clear();
                } else {
                    departCadreSelection = new Point(x, y);
                    arriveeCadreSelection = new Point(x, y);
                    if ((e.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK) == 0)
                        selectionCourante.clear();
                }
            }
        }
    }

    public void mouseReleased(MouseEvent e)
    {
        removeMouseMotionListener(this);

        if (creationLien && enabled) {
            creationLien = false;
            ZElement cibleLien = chercheElement(e.getX(), e.getY());
            if (cibleLien != null) {
                lienTemp.setElement(cibleLien, Constantes.MCDENTITE2);
                x2 = e.getX();
                y2 = e.getY();
            }
            if (peutCreerLien(lienTemp.getElement(Constantes.MCDENTITE1), lienTemp
                    .getElement(Constantes.MCDENTITE2))){
                addLien(lienTemp);
            }
            else
                lienTemp.clearElement();
           
            repaint();
        } else if (enabled) {
            elementPress = null;
            if (arriveeCadreSelection != null) {
                selectionCourante.addAll(selectionTemporaire);
                selectionTemporaire.clear();
                departCadreSelection = null;
                arriveeCadreSelection = null;
            }
            repaint();
        }
        if (actionListener != null)
            actionListener.actionPerformed(new ActionEvent(this,
                    ActionEvent.ACTION_PERFORMED, ""));

        /* Correction Bug Graphique */
        if (getPreferredSize().height > getSize().height
                || getPreferredSize().width > getSize().width
        /*
         * || getPreferredSize().height < getSize().height ||
         * getPreferredSize().width < getSize().width
         */)
            this.setSize(getPreferredSize());

    }

    public void mouseDragged(MouseEvent e)
    {
        Point point = new Point();
       
        if (creationLien && enabled) {
            x2 = e.getX();
            y2 = e.getY();
            repaint();
        } else if (enabled) {
            if (elementPress != null) {
                for (Map.Entry<ZElement, Point> entry : positionsRelatives.entrySet()) {
                    Point posRel = entry.getValue();
                    int xCentrage = (int) posRel.getX();
                    int yCentrage = (int) posRel.getY();
                    point.x = e.getX() - xCentrage < 0 ? 0 : e.getX() - xCentrage;
                    point.y = e.getY() - yCentrage < 0 ? 0 : e.getY() - yCentrage;

                    ZElement elem = entry.getKey();
                    elem.setPosition(point);
                }
                repaint();
            }
            else if (arriveeCadreSelection != null) {
                arriveeCadreSelection.x = e.getX();
                arriveeCadreSelection.y = e.getY();
                selectionTemporaire.clear();
                for (ZElement elem : zelements)
                    if (elem.isInside(departCadreSelection.x, departCadreSelection.y, arriveeCadreSelection.x, arriveeCadreSelection.y))
                        selectionTemporaire.add(elem);
                repaint();
            }
        }
    }

    public void mouseEntered(MouseEvent e)
    {
    }

    public void mouseExited(MouseEvent e)
    {
    }

    public void mouseMoved(MouseEvent e)
    {
    }
}
TOP

Related Classes of org.analyse.core.gui.zgraph.ZGraphique

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.