import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.List; /** * Cette classe permet d'afficher l'ensemble des éléments du projet sous la forme d'un diagramme UML. */ public class UmlDiagram extends JPanel implements MouseListener, MouseMotionListener { private Project _project; private List _classes; private List _links; private Object _selected; /** * Constructeur - Crée un nouveau diagramme UML à partir d'un projet. * @param p Le projet associé. */ public UmlDiagram(Project p){ _project = p; this.addMouseListener(this); this.addMouseMotionListener(this); } /** * Dessine les éléments du projet sous la forme d'un diagramme UML. * @param g L'objet graphique */ @Override public void paintComponent(Graphics g){ Font font = new Font("Arial", Font.PLAIN, 14); for(Class a : _classes){ int posX = a.getPosX() - (a.getSizeX()/2); int posY = a.getPosY() - (a.getSizeY()/2); //Dessin du rectangle g.setColor(Color.GRAY); g.fillRoundRect(posX, posY, a.getSizeX(), a.getSizeY(), 10, 10); g.setColor(Color.BLACK); //Dessin du nom de la classe int posCounter = posY + font.getSize(); FontMetrics metrics = this.getFontMetrics(font); g.setFont(font); g.drawString(a.getName(), posX + a.getSizeX()/2 - metrics.stringWidth(a.getName())/2, posCounter); posCounter += 5; //Ligne de séparation g.drawLine(posX, posY + font.getSize() + 5, posX + a.getSizeX()-1, posY + font.getSize() + 5); //Affichage des attributs for(Attribute b : a.getAttributes()){ posCounter += font.getSize(); g.drawString(b.getAccess() + " " + b.getName() + " : " + b.getType(), posX, posCounter); } posCounter += 5; //Ligne de séparation g.drawLine(posX, posCounter, posX + a.getSizeX()-1, posCounter); //Dessin des méthodes for(Method m : a.getMethods()){ posCounter += font.getSize(); String chain = m.getAccess() + " " + m.getName() + "("; for(Argument ar : m.getArguments()){ chain += ar.getName() + " : " + ar.getType() + ", "; } chain = chain.substring(0, chain.length()-2); chain += ") : " + m.getType(); g.drawString(chain, posX, posCounter); } //Si la classe est sélectionnée if((Class)_selected == a){ AppThinker.getWindow().getStatusbar().setSizeLabel(a.getSizeX(), a.getSizeY()); //Top Left g.fillOval(posX-4, posY-4, 8, 8); //Top g.fillRect(posX + (a.getSizeX()/2)-4, posY-4, 8, 8); //Top Right g.fillOval(posX + a.getSizeX()-4, posY-4, 8, 8); //Right g.fillRect(posX + a.getSizeX()-4, posY + (a.getSizeY()/2)-4, 8, 8); //Bottom Right g.fillOval(posX + a.getSizeX()-4, posY + a.getSizeY()-4, 8, 8); //Bottom g.fillRect(posX + (a.getSizeX()/2)-4, posY + a.getSizeY()-4,8, 8); //Bottom Left g.fillOval(posX - 4, posY + a.getSizeY()-4, 8, 8); //Left g.fillRect(posX -4, posY + (a.getSizeY()/2)-4, 8, 8); //Total rectangle g.drawRect(posX, posY, a.getSizeX(), a.getSizeY()); } else AppThinker.getWindow().getStatusbar().setSizeLabel(0, 0); } AppThinker.getProject().getGrid().updateUI(); } /** * Mets à jour graphiquement le diagramme UML. */ public void displayDiagram(){ _classes = _project.getClasses(); _links = _project.getLinks(); this.repaint(); } /** * Récupère l'élément sélectionné dans la grille. * @return L'élément sélectionné dan sla grille. */ public Object getSelected(){ return this._selected; } /** * Récupération de l'objet cliqué * @param getX Les coordonnées de la souris sur l'axe X. * @param getY Les coordonnées de la souris sur l'axe Y. */ public void select(int getX, int getY){ //On cherche l'objet sélectionné boolean classSelected = false; boolean linkSelected = false; for(Class a : _classes){ int posX = a.getPosX()-(a.getSizeX()/2); int posY = a.getPosY()-(a.getSizeY()/2); if(getX >= posX && getX <= (posX + a.getSizeX())){ if(getY >= posY && getY <= (posY + a.getSizeY())){ classSelected = true; _selected = a; break; } } } if(classSelected == false && linkSelected == false) _selected = null; this.repaint(); } //Actions de la souris sur le diagramme UML /** * Action du clic de la souris sur le diagramme. * @param e L'événement souris. */ @Override public void mouseClicked(MouseEvent e) { if(e.getClickCount() == 2){ System.out.println("Modification des propriétés"); } } /** * Bouton de la souris pressé sur la grille. On récupère l'outil sélectionné pour parvenir à l'action. * @param e L'événement souris. */ @Override public void mousePressed(MouseEvent e) { int tool = AppThinker.getWindow().getToolbar().getCurrentTool(); switch(tool){ //On essaie de sélectionner un élément case AppThinkerToolbar.EDIT_TOOL: System.out.println("On édite un élément."); break; case AppThinkerToolbar.DELETE_TOOL: System.out.println("On supprime un élément."); this.select(e.getX(), e.getY()); if(_selected instanceof Class){ Class a = (Class)_selected; AppThinker.getProject().getClasses().remove(a); } this.displayDiagram(); break; case AppThinkerToolbar.COPY_TOOL: System.out.println("On copie un élément."); break; case AppThinkerToolbar.PASTE_TOOL: System.out.println("On colle un élément."); break; //On essaie d'ajouter une classe case AppThinkerToolbar.CLASS_TOOL: Class newClass = new Class(e.getX(), e.getY(), Class.RECTANGLE); AppThinker.getProject().addClass(newClass); break; case AppThinkerToolbar.ASSOCIATION_TOOL: System.out.println("On ajoute une association"); break; case AppThinkerToolbar.LINK_TOOL: System.out.println("On ajoute un lien"); break; default: this.select(e.getX(), e.getY()); break; } this.displayDiagram(); } @Override public void mouseReleased(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } /** * Déplacer un élément en cliquant et déplaçant la souris. * @param e Evénement souris */ @Override public void mouseDragged(MouseEvent e) { if(_selected instanceof Class){ Class a = (Class)_selected; a.setPosX(e.getX()); a.setPosY(e.getY()); } this.repaint(); } /** * La souris bouge dans la grille. On affiche les coordonnées de la souris dans la statusbar. * @param e L'événement souris. */ @Override public void mouseMoved(MouseEvent e) { AppThinker.getWindow().getStatusbar().setPosLabel(e.getX(), e.getY()); } }