import javax.imageio.ImageIO; import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.awt.*; import java.awt.event.*; import java.util.ArrayList; import java.util.Vector; /** * Classe permettant la création de fenêtres pour la modification des propriétés des classes. * @author V.BOULANGER */ public class ClassPropertiesWindow extends JDialog { private UmlDiagram _umlDiagram; private Class _class; private JTextField _nameField; private JTable _attributesTable; private JScrollPane _scrollAttributes; private String[] _attributesColumns = {"Name", "Access modifier", "Type", "Static", "Final", "Abstract", "Synchronised", "Volatile", "Transient"}; private DefaultTableModel _attributeModel; private JTable _methodsTable; private JScrollPane _scrollMethods; private String[] _methodsColumns = {"C", "Name", "Access modifier", "Type", "Arguments", "Static", "Final", "Abstract", "Synchronised", "Volatile", "Transient"}; private DefaultTableModel _methodModel; /** * Constructeur - Crée une instance de la fenêtre de propriétés de classe à partir d'un diagramme et de la classe à modifier. * @param umlDiagram Le diagramme qui contient la classe. * @param a La classe à modifier. */ public ClassPropertiesWindow(UmlDiagram umlDiagram, Class a){ _umlDiagram = umlDiagram; _class = a; //Paramétrage de la fenêtre this.setTitle("Edit properties - " + a.getName()); this.setModal(true); this.setSize(new Dimension(800, 375)); Image img = null; try { img = ImageIO.read(AppThinker.class.getResource("img/logoAppThinker.png")); } catch (Exception ex) { } this.setIconImage(img); this.setResizable(false); this.setLocationRelativeTo(null); this.setLayout(new BorderLayout()); //Espace général de la fenêtre JPanel generalPanel = new JPanel(); generalPanel.setLayout(new BoxLayout(generalPanel, BoxLayout.Y_AXIS)); //Espace de modification du nom JPanel namePan = new JPanel(); namePan.setLayout(new BoxLayout(namePan, BoxLayout.X_AXIS)); JLabel nameLbl = new JLabel("Name : "); _nameField = new JTextField(); _nameField.setPreferredSize(new Dimension(300, 20)); _nameField.setText(a.getName()); namePan.add(nameLbl); namePan.add(_nameField); generalPanel.add(namePan); //Radio bouton pour définir la classe principale JRadioButton mainRadio = new JRadioButton("This is the main class"); mainRadio.setToolTipText("The main class is the entry point of the application. It appears in red on the diagram."); mainRadio.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { defineMainClass(a); refreshGraphics(); } }); ButtonGroup bg = new ButtonGroup(); bg.add(mainRadio); if(_umlDiagram.getMainClass() == a) mainRadio.setSelected(true); else mainRadio.setSelected(false); generalPanel.add(mainRadio); JLabel attrLbl = new JLabel("Edit attributes"); generalPanel.add(attrLbl); //Espace de modification des attributs JPanel attributesPan = new JPanel(); attributesPan.setLayout(new BoxLayout(attributesPan, BoxLayout.X_AXIS)); _attributeModel = new DefaultTableModel(_attributesColumns, 0); _attributesTable = new JTable(_attributeModel); _scrollAttributes = new JScrollPane(_attributesTable); _scrollAttributes.setPreferredSize(new Dimension(350, 100)); attributesPan.add(_scrollAttributes); JPanel attributesTableModifier = new JPanel(); attributesTableModifier.setLayout(new BoxLayout(attributesTableModifier, BoxLayout.Y_AXIS)); JButton addAttribute = new JButton(" + "); addAttribute.setToolTipText("Add a new attribute."); addAttribute.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { addAttribute(); } }); attributesTableModifier.add(addAttribute); JButton removeAttribute = new JButton(" - "); removeAttribute.setToolTipText("Remove the selected attribute."); removeAttribute.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { removeAttribute(); } }); attributesTableModifier.add(removeAttribute); JButton upAttribute = new JButton("▲"); upAttribute.setToolTipText("Go up the selected attribute."); upAttribute.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int selected = _attributesTable.getSelectedRow(); if(_class.upAttribute(selected)){ refreshGraphics(); listAttributes(); _attributesTable.setRowSelectionInterval(selected - 1, selected - 1); } } }); attributesTableModifier.add(upAttribute); JButton downAttribute = new JButton("▼"); downAttribute.setToolTipText("Go down the selected attribute."); downAttribute.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int selected = _attributesTable.getSelectedRow(); if(_class.downAttribute(selected)){ refreshGraphics(); listAttributes(); _attributesTable.setRowSelectionInterval(selected + 1, selected + 1); } } }); attributesTableModifier.add(downAttribute); attributesPan.add(attributesTableModifier); generalPanel.add(attributesPan); JLabel methLbl = new JLabel("Edit methods"); generalPanel.add(methLbl); //Espace de modification des méthodes JPanel methodsPan = new JPanel(); methodsPan.setLayout(new BoxLayout(methodsPan, BoxLayout.X_AXIS)); _methodModel = new DefaultTableModel(_methodsColumns, 0); _methodsTable = new JTable(_methodModel); _methodsTable.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { Point p = e.getPoint(); int col = _methodsTable.columnAtPoint(p); int row = _methodsTable.rowAtPoint(p); if (col == 4) openArgumentsWindow(_class.getMethods().get(row)); } }); _scrollMethods = new JScrollPane(_methodsTable); _scrollMethods.setPreferredSize(new Dimension(350, 100)); methodsPan.add(_scrollMethods); JPanel methodsTableModifier = new JPanel(); methodsTableModifier.setLayout(new BoxLayout(methodsTableModifier, BoxLayout.Y_AXIS)); JButton addMethod = new JButton(" + "); addMethod.setToolTipText("Add a new method."); addMethod.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { addMethod(); } }); methodsTableModifier.add(addMethod); JButton removeMethod = new JButton(" - "); removeMethod.setToolTipText("Remove the selected method."); removeMethod.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { removeMethod(); } }); methodsTableModifier.add(removeMethod); JButton upMethod = new JButton("▲"); upMethod.setToolTipText("Go up the selected method."); upMethod.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int selected = _methodsTable.getSelectedRow(); if(_class.upMethod(selected)){ refreshGraphics(); listMethods(); _methodsTable.setRowSelectionInterval(selected - 1, selected - 1); } } }); methodsTableModifier.add(upMethod); JButton downMethod = new JButton("▼"); downMethod.setToolTipText("Go down the selected method."); downMethod.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int selected = _methodsTable.getSelectedRow(); if(_class.downMethod(selected)){ refreshGraphics(); listMethods(); _methodsTable.setRowSelectionInterval(selected + 1, selected + 1); } } }); methodsTableModifier.add(downMethod); JButton overloadMethod = new JButton(" O "); overloadMethod.setToolTipText("Overload this method."); overloadMethod.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { overloadMethod(); } }); methodsTableModifier.add(overloadMethod); methodsPan.add(methodsTableModifier); generalPanel.add(methodsPan); this.add(generalPanel, BorderLayout.CENTER); //Import des attributs et méthodes dans les tableaux this.listAttributes(); this.listMethods(); this.addWindowListener(new WindowListener() { @Override public void windowOpened(WindowEvent e) { } //On enregistre à la fermeture de la fenêtre @Override public void windowClosing(WindowEvent e) { saveClass(); refreshGraphics(); dispose(); } @Override public void windowClosed(WindowEvent e) { } @Override public void windowIconified(WindowEvent e) { } @Override public void windowDeiconified(WindowEvent e) { } @Override public void windowActivated(WindowEvent e) { } @Override public void windowDeactivated(WindowEvent e) { } }); this.setVisible(true); } /** * Définit la classe principale du diagramme. * @param a La classe principale du diagramme. */ public void defineMainClass(Class a){ _umlDiagram.setMainClass(a); refreshGraphics(); } /** * Ouvre une fenêtre d'édition des arguments pour la méthode sélectionnée * @param m La méthode dans laquelle seront modifiés les arguments. */ public void openArgumentsWindow(Method m){ ArgumentsPropertiesWindow argsWin = new ArgumentsPropertiesWindow(this, _umlDiagram, m); } /** * Récupère la classe en cours d'édition. * @return La classe en cours d'édition. */ public Class getEditingClass(){ return _class; } /** * Ajoute un attribut à la classe et rafraîchit la liste des attributs. */ public void addAttribute(){ this.saveAttributes(); _class.addAttribute(new Attribute()); this.listAttributes(); refreshGraphics(); } /** * Retire un attribut à la classe et rafraîchit la liste des attributs. */ public void removeAttribute(){ int i = _attributesTable.getSelectedRow(); if(i != -1){ this.saveAttributes(); _class.removeAttribute(i); this.listAttributes(); refreshGraphics(); } } /** * Ajoute une méthode à la classe et rafraîchit la liste des méthodes. */ public void addMethod(){ this.saveMethods(); _class.addMethod(new Method()); this.listMethods(); refreshGraphics(); } /** * Ajoute une méthode à la classe et rafraîchit la liste des méthodes. * @param index Le rang d'insertion de la méthode. * @param m La méthode à insérer. */ public void addMethod(int index, Method m){ this.saveMethods(); _class.addMethod(index, m); this.listMethods(); refreshGraphics(); } /** * Retire une méthode à la classe et rafraîchit la liste des méthodes. */ public void removeMethod(){ int i = _methodsTable.getSelectedRow(); if(i != -1){ this.saveMethods(); _class.removeMethod(i); this.listMethods(); refreshGraphics(); } } /** * On surcharge la méthode avec un argument en plus qui peut être modifié par la suite. */ public void overloadMethod(){ int index = _methodsTable.getSelectedRow(); if(index != -1){ Method m = _class.getMethods().get(index); java.util.List args = new ArrayList(); //On ajoute un argument de plus que la méthode à surcharger args.addAll(m.getArguments()); args.add(new Argument()); Method m1 = new Method(m.getAccess(), m.getType(), m.getName(), args, m.isConstructor(), m.isStatic(), m.isFinal(), m.isAbstract(), m.isSynchronized(), m.isVolatile(), m.isTransient()); this.addMethod(index + 1, m1); this.openArgumentsWindow(m1); } } /** * Affiche la liste des attributs de la classe dans le tableau */ public void listAttributes(){ //Import des attributs dans la table _attributeModel.setDataVector((Object[][]) null, _attributesColumns); for(Attribute attr : _class.getAttributes()){ String access = (attr.getAccess() == "+") ? "PUBLIC" : (attr.getAccess() == "#") ? "PROTECTED" : "PRIVATE"; _attributeModel.addRow(new Object[]{attr.getName(), access, attr.getType(), attr.isStatic(), attr.isFinal(), attr.isAbstract(), attr.isSynchronized(), attr.isVolatile(), attr.isTransient()}); } //On ajoute les contrôles pour chaque colonne String[] access = { "PRIVATE", "PUBLIC", "PROTECTED" }; JComboBox accessComboBox = new JComboBox(access); accessComboBox.setEditable(true); _attributesTable.getColumn(_attributesColumns[1]).setCellEditor(new DefaultCellEditor(accessComboBox)); String[] types = { "boolean", "char", "byte", "short", "int", "long", "float", "double", "String" }; JComboBox typeComboBox = new JComboBox(types); typeComboBox.setEditable(true); _attributesTable.getColumn(_attributesColumns[2]).setCellEditor(new DefaultCellEditor(typeComboBox)); _attributesTable.getColumn(_attributesColumns[3]).setCellEditor(new DefaultCellEditor(new JCheckBox())); _attributesTable.getColumn(_attributesColumns[4]).setCellEditor(new DefaultCellEditor(new JCheckBox())); _attributesTable.getColumn(_attributesColumns[5]).setCellEditor(new DefaultCellEditor(new JCheckBox())); _attributesTable.getColumn(_attributesColumns[6]).setCellEditor(new DefaultCellEditor(new JCheckBox())); _attributesTable.getColumn(_attributesColumns[7]).setCellEditor(new DefaultCellEditor(new JCheckBox())); _attributesTable.getColumn(_attributesColumns[8]).setCellEditor(new DefaultCellEditor(new JCheckBox())); } /** * Affiche la liste des méthodes de la classe dans le tableau. */ public void listMethods(){ //Import des méthodes dans la table _methodModel.setDataVector((Object[][]) null, _methodsColumns); for(Method meth : _class.getMethods()){ String access = (meth.getAccess() == "-") ? "PRIVATE" : (meth.getAccess() == "#") ? "PROTECTED" : "PUBLIC"; _methodModel.addRow(new Object[]{meth.isConstructor(), meth.getName(), access, meth.getType(), "[EDIT]", meth.isStatic(), meth.isFinal(), meth.isAbstract(), meth.isSynchronized(), meth.isVolatile(), meth.isTransient()}); } //On ajoute les contrôles pour chaque colonne String[] access = { "PRIVATE", "PUBLIC", "PROTECTED" }; JComboBox accessComboBox = new JComboBox(access); accessComboBox.setEditable(true); _methodsTable.getColumn(_methodsColumns[0]).setCellEditor(new DefaultCellEditor(new JCheckBox())); _methodsTable.getColumn(_methodsColumns[2]).setCellEditor(new DefaultCellEditor(accessComboBox)); String[] types = { "boolean", "char", "byte", "short", "int", "long", "float", "double", "String" }; JComboBox typeComboBox = new JComboBox(types); typeComboBox.setEditable(true); _methodsTable.getColumn(_methodsColumns[3]).setCellEditor(new DefaultCellEditor(typeComboBox)); JTextField argsField = new JTextField(); argsField.setEnabled(false); _methodsTable.getColumn(_methodsColumns[4]).setCellEditor(new DefaultCellEditor(argsField)); _methodsTable.getColumn(_methodsColumns[5]).setCellEditor(new DefaultCellEditor(new JCheckBox())); _methodsTable.getColumn(_methodsColumns[6]).setCellEditor(new DefaultCellEditor(new JCheckBox())); _methodsTable.getColumn(_methodsColumns[7]).setCellEditor(new DefaultCellEditor(new JCheckBox())); _methodsTable.getColumn(_methodsColumns[8]).setCellEditor(new DefaultCellEditor(new JCheckBox())); _methodsTable.getColumn(_methodsColumns[9]).setCellEditor(new DefaultCellEditor(new JCheckBox())); _methodsTable.getColumn(_methodsColumns[10]).setCellEditor(new DefaultCellEditor(new JCheckBox())); } /** * Sauvegarde les attributs pour la classe en cours. */ public void saveAttributes(){ //Enregistrement des attributs _attributesTable.editCellAt(0,0); for(int i = 0; i <= _attributeModel.getRowCount()-1; i++){ Vector vect = (Vector)_attributeModel.getDataVector().elementAt(i); String access = vect.get(1).toString(); _class.getAttributes().get(i).setName(vect.get(0).toString()); _class.getAttributes().get(i).setAccess((access == "PUBLIC") ? Attribute.PUBLIC : (access == "PROTECTED") ? Attribute.PROTECTED : Attribute.PRIVATE); _class.getAttributes().get(i).setType(vect.get(2).toString()); _class.getAttributes().get(i).setStatic((boolean) vect.get(3)); _class.getAttributes().get(i).setFinal((boolean) vect.get(4)); _class.getAttributes().get(i).setAbstract((boolean) vect.get(5)); _class.getAttributes().get(i).setSynchronized((boolean) vect.get(6)); _class.getAttributes().get(i).setVolatile((boolean) vect.get(7)); _class.getAttributes().get(i).setTransient((boolean) vect.get(8)); } } /** * Sauvegarde les méthodes pour la classe en cours. */ public void saveMethods(){ //Enregistrement des méthodes _methodsTable.editCellAt(0,0); for(int i = 0; i <= _methodModel.getRowCount()-1; i++){ Vector vect = (Vector)_methodModel.getDataVector().elementAt(i); String access = vect.get(2).toString(); _class.getMethods().get(i).setConstructor((boolean)vect.get(0)); _class.getMethods().get(i).setName(vect.get(1).toString()); _class.getMethods().get(i).setAccess((access == "PRIVATE") ? Method.PRIVATE : (access == "PROTECTED") ? Method.PROTECTED : Method.PUBLIC); _class.getMethods().get(i).setType(vect.get(3).toString()); _class.getMethods().get(i).setStatic((boolean) vect.get(5)); _class.getMethods().get(i).setFinal((boolean) vect.get(6)); _class.getMethods().get(i).setAbstract((boolean) vect.get(7)); _class.getMethods().get(i).setSynchronized((boolean) vect.get(8)); _class.getMethods().get(i).setVolatile((boolean) vect.get(9)); _class.getMethods().get(i).setTransient((boolean) vect.get(10)); } } /** * Sauvegarde l'ensemble de la classe. */ public void saveClass(){ //Changement du nom de la classe _class.setName(_nameField.getText()); //Sauvegarde des attributs et méthodes saveAttributes(); saveMethods(); } /** * Rafraîchit la classe graphiquement. */ public void refreshGraphics(){ this._class.computeMinSize(); _umlDiagram.repaint(); } }