Résolution des issues #15 et #16 édition multiple

This commit is contained in:
2021-04-21 16:07:33 +02:00
parent e8c19ba82f
commit c70f15b6c2
66 changed files with 3492 additions and 2563 deletions

View File

@@ -1,3 +1,3 @@
#Wed Apr 14 15:11:50 CEST 2021
#Tue Apr 20 14:42:09 CEST 2021
version=1.0.0
showHomeAtStartup=true

View File

@@ -35,7 +35,8 @@ public class AppThinker {
_appProperties = new ATProperties("app.properties");
changelog = new ArrayList<String>();
changelog.add("#37 Manage user preferences");
changelog.add("#16 Workspace");
changelog.add("#15 Multi-project and multi-composition editing");
_splash = new Splashscreen();

View File

@@ -19,8 +19,18 @@ public class HomeFrameController {
_homeFrame.setController(this);
}
public void startNewProject() {
_windowController.startNewProject();
/**
* Ajoute un projet vide à la fenêtre.
*/
public void newBlankProject() {
_windowController.newBlankProject();
}
/**
* Ajoute un projet UML à la fenêtre.
*/
public void newUmlProject() {
_windowController.newUmlProject();
}
public void openProject(String path) {

View File

@@ -1,6 +1,7 @@
package com.thinkode.appthinker.controllers;
import com.thinkode.appthinker.AppThinker;
import com.thinkode.appthinker.models.Composition;
import com.thinkode.appthinker.models.Project;
import com.thinkode.appthinker.models.UmlDiagram;
import com.thinkode.appthinker.views.AboutWindow;
@@ -17,7 +18,7 @@ import java.net.URL;
public class WindowController {
private Project _project;
private java.util.List<Project> _projects;
private Window _atWindow;
/**
@@ -27,28 +28,138 @@ public class WindowController {
*/
public WindowController(Window atWindow) {
_atWindow = atWindow;
_project = null;
_projects = new java.util.ArrayList<Project>();
atWindow.setController(this);
atWindow.setVisible(true);
String state = AppThinker.getATProperties().getProperty("showHomeAtStartup");
if (state.equals("true")) showHomeFrame();
refreshWorkspace();
}
/**
* Démarre un nouveau projet
* Ouvre une composition dans la fenêtre
*/
public void startNewProject() {
if (_project != null) closeProject();
_project = new Project();
public void openComposition(int projectListId, int compositionListId) {
UmlDiagramFrame frame = new UmlDiagramFrame();
UmlDiagram comp = (UmlDiagram) _projects.get(projectListId).getCompositions().get(compositionListId);
UmlDiagramController umlController = new UmlDiagramController(frame, comp);
_atWindow.addCompositionFrame(comp.getName(), _projects.get(projectListId).getName(), frame);
}
/**
* Ajoute un nouveau projet vide à la fenêtre en cours
*/
public void newBlankProject() {
Project proj = new Project();
_projects.add(proj);
_atWindow.setStatusMessage("The blank project has been created.");
refreshWorkspace();
}
/**
* Ajoute un nouveau projet vide à la fenêtre en cours
*/
public void newUmlProject() {
Project proj = new Project();
//Création d'une composition UML dans le projet
UmlDiagram umlDiagram = new UmlDiagram();
_project.setComposition(umlDiagram);
proj.addComposition(umlDiagram);
_projects.add(proj);
_atWindow.setStatusMessage("The UML project has been created.");
refreshWorkspace();
}
//Création d'une composition UML
UmlDiagramFrame umlFrame = new UmlDiagramFrame();
new UmlDiagramController(umlFrame, umlDiagram);
_atWindow.displayComposition(umlFrame);
_atWindow.setStatusMessage("The project has been created.");
/**
* Ajoute une composition UML à un projet
*/
public void addUmlComposition(int projectListId) {
_projects.get(projectListId).addComposition(new UmlDiagram());
refreshWorkspace();
}
/**
* Renomme le projet sélectionné
*/
public void renameProject(int projectListId, String newName) {
Project project = _projects.get(projectListId);
if (!projectNameExists(project, newName)) {
_projects.get(projectListId).setName(newName);
refreshWorkspace();
} else {
_atWindow.showMessage("Another project in the workspace has the same name ! Please choose another name.");
}
}
/**
* Vérifie si le projet peut être modifié avec ce nom
*/
private boolean projectNameExists(Project project, String name) {
for (Project p : _projects) {
if (p.getName().equals(name) && p != project) return true;
}
return false;
}
/**
* Supprime un projet existant
*/
public void deleteProject(int projectListId) {
Project project = _projects.get(projectListId);
for (Composition comp : project.getCompositions()) {
deleteCompositionFrame(project.getName(), comp.getName());
}
_projects.remove(projectListId);
refreshWorkspace();
}
/**
* Renomme la composition d'un projet
*/
public void renameComposition(int projectListId, int compositionListId, String newName) {
Project project = _projects.get(projectListId);
Composition comp = project.getCompositions().get(compositionListId);
if (!compositionNameExists(project, comp, newName)) {
String oldName = comp.getName();
comp.setName(newName);
refreshWorkspace();
_atWindow.updateCompositionTitle(project.getName(), oldName, newName);
} else
_atWindow.showMessage("Another composition in the project has the same name ! Please choose another name.");
}
/**
* Vérifie si la composition peut être modifiée avec ce nom
*/
private boolean compositionNameExists(Project project, Composition composition, String name) {
for (Composition c : project.getCompositions()) {
if (c.getName().equals(name) && c != composition) return true;
}
return false;
}
/**
* Supprimer une composition d'un projet
*/
public void deleteComposition(int projectListId, int compositionListId) {
Project project = _projects.get(projectListId);
Composition comp = project.getCompositions().get(compositionListId);
project.removeComposition(compositionListId);
refreshWorkspace();
deleteCompositionFrame(project.getName(), comp.getName());
}
/**
* Retire la CompositionFrame du widget
*/
public void deleteCompositionFrame(String projectName, String compositionName) {
_atWindow.deleteCompositionFrame(projectName, compositionName);
}
/**
* Commande la mise à jour du Workspace
*/
public void refreshWorkspace() {
_atWindow.refreshWorkspace(this.getProjects());
}
/**
@@ -58,7 +169,7 @@ public class WindowController {
//Affichage de la page d'accueil
HomeFrame homeFrame = new HomeFrame();
new HomeFrameController(homeFrame, this);
_atWindow.displayComposition(homeFrame);
_atWindow.addCompositionFrame("Home page", "AppThinker", homeFrame);
}
/**
@@ -81,11 +192,15 @@ public class WindowController {
try {
if (ois != null) {
ois.close();
//Si un projet est ouvert, on le ferme d'abord
if (_project != null) closeProject();
_project = project;
//this.displayComposition(_project.getComposition());
//this._statusbar.setStatusMessage("The project has been opened.");
//Ajout du projet à la fenêtre en cours
for (Project p : _projects) {
}
if (!projectAlreadyOpened(project)) {
_projects.add(project);
refreshWorkspace();
_atWindow.setStatusMessage("The project has been opened.");
}
}
} catch (final IOException ex) {
ex.printStackTrace();
@@ -94,43 +209,43 @@ public class WindowController {
}
/**
* Retourne le nom du projet
* Vérifie si le projet est déjà dans le workspace
*
* @return
*/
private boolean projectAlreadyOpened(Project project) {
for (Project p : _projects) {
if (p.getName().equals(project.getName())) return true;
}
return false;
}
/**
* Retourne la liste des projets actuellement ouverts
*
* @return Le nom du projet
*/
public String getProjectName() {
return _project.getName();
public java.util.List<Project> getProjects() {
return _projects;
}
public String getProjectPath() {
return _project.getPath();
/**
* Sauvegarder le projet
*/
public void saveProject(int projectListId) {
System.out.println("test");
_projects.get(projectListId).saveProject();
}
/**
* Sauvegarder le projet sous
*/
public void saveProject() {
}
/**
* Sauvegarder le projet
*/
public void saveAsProject() {
}
/**
* Ferme la composition projet existant
*/
public void closeProject() {
_project = null;
_atWindow.closeProject();
showHomeFrame();
public void saveAsProject(int projectListId) {
_projects.get(projectListId).saveAsProject();
}
//Méthodes relatives à la barre de menu
public void exitApplication() {
System.exit(0);
}
@@ -146,6 +261,4 @@ public class WindowController {
System.out.println("An error as occur when trying to check for updates : " + ex.toString());
}
}
}

View File

@@ -0,0 +1 @@
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cls-1{fill:#d79400;}.cls-2{fill:#ffd55e;}</style></defs><title>blankProject</title><rect class="cls-1" x="25" y="40" width="173" height="64" rx="8.54"/><rect class="cls-2" x="15" y="94" width="470" height="351" rx="8.54"/></svg>

After

Width:  |  Height:  |  Size: 339 B

View File

@@ -0,0 +1 @@
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cls-1{fill:#696972;}</style></defs><title>closeTab</title><path class="cls-1" d="M249.5,17C121.09,17,17,121.09,17,249.5S121.09,482,249.5,482,482,377.91,482,249.5,377.91,17,249.5,17ZM377.2,375.36h0a38,38,0,0,1-53.74.09L249.8,302,175.68,376.4a38,38,0,0,1-53.74.09h0a38,38,0,0,1-.09-53.74L196,248.38,122.3,175a38,38,0,0,1-.09-53.74h0a38,38,0,0,1,53.74-.09l73.67,73.41,72.7-73a38,38,0,0,1,53.74-.09h0a38,38,0,0,1,.09,53.74l-72.7,72.95,73.66,73.42A38,38,0,0,1,377.2,375.36Z"/></svg>

After

Width:  |  Height:  |  Size: 588 B

View File

@@ -0,0 +1 @@
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cls-1{fill:#3fa9f5;}.cls-2{fill:#696972;}</style></defs><title>deleteComposition</title><path class="cls-1" d="M315,52H119.54A8.55,8.55,0,0,0,111,60.54V440.46a8.55,8.55,0,0,0,8.54,8.54H380.46a8.55,8.55,0,0,0,8.54-8.54V126Z"/><rect class="cls-2" x="226.14" y="140.65" width="48" height="219" rx="24" transform="translate(247.88 -103.6) rotate(44.63)"/><rect class="cls-2" x="226.85" y="140.64" width="48" height="219" rx="24" transform="translate(-103.4 252.91) rotate(-45.37)"/></svg>

After

Width:  |  Height:  |  Size: 595 B

View File

@@ -0,0 +1 @@
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cls-1{fill:#696972;}</style></defs><title>homePage</title><path class="cls-1" d="M246.83,33.38,45.66,184.49A5.28,5.28,0,0,0,48.83,194H451.17a5.28,5.28,0,0,0,3.17-9.51L253.17,33.38A5.28,5.28,0,0,0,246.83,33.38Z"/><polygon class="cls-1" points="69.87 194 433 194 433 448 211 448 211 353 134 353 134 448 70 448 69.87 194"/></svg>

After

Width:  |  Height:  |  Size: 437 B

View File

@@ -0,0 +1 @@
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cls-1{fill:#3fa9f5;}.cls-2{fill:#696972;}</style></defs><title>newComposition</title><path class="cls-1" d="M315,51H119.54A8.55,8.55,0,0,0,111,59.54V439.46a8.55,8.55,0,0,0,8.54,8.54H380.46a8.55,8.55,0,0,0,8.54-8.54V125Z"/><rect class="cls-2" x="226" y="140" width="48" height="219" rx="24"/><rect class="cls-2" x="226.5" y="139.5" width="48" height="219" rx="24" transform="translate(1.5 499.5) rotate(-90)"/></svg>

After

Width:  |  Height:  |  Size: 526 B

View File

@@ -0,0 +1 @@
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cls-1,.cls-2{fill:#696972;}.cls-2{font-size:254.19px;font-family:MyriadPro-Regular, Myriad Pro;letter-spacing:0em;}.cls-3{letter-spacing:0em;}</style></defs><title>rename</title><rect class="cls-1" x="122" y="113" width="35" height="278"/><text class="cls-2" transform="translate(170.56 336.77) scale(1.11 1)">A<tspan class="cls-3" x="156.58" y="0">a</tspan></text><path class="cls-1" d="M231.5,84H156.73l-15.26,28a2.41,2.41,0,0,1-1,1h91a14.5,14.5,0,0,0,0-29Z"/><path class="cls-1" d="M137.14,112,121.88,84H48.5a15.67,15.67,0,0,0-4.91,1A14.25,14.25,0,0,0,34,98.5a14.06,14.06,0,0,0,1.3,6,14.32,14.32,0,0,0,5.77,6A17.57,17.57,0,0,0,48.5,113h89.61A2.41,2.41,0,0,1,137.14,112Z"/><path class="cls-1" d="M47.85,420h74.77l15.26-28a2.41,2.41,0,0,1,1-1h-91a14.5,14.5,0,0,0,0,29Z"/><path class="cls-1" d="M142.21,392l15.27,28h73.37a15.67,15.67,0,0,0,4.91-.95,14.74,14.74,0,0,0,6.53-4.63,14.52,14.52,0,0,0,3.06-8.92,14.06,14.06,0,0,0-1.3-6,14.32,14.32,0,0,0-5.77-6,17.53,17.53,0,0,0-7.43-2.5H141.24A2.41,2.41,0,0,1,142.21,392Z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1 @@
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cls-1,.cls-4{fill:none;}.cls-1,.cls-2,.cls-3,.cls-4{stroke:#3fa9f5;stroke-miterlimit:10;}.cls-1,.cls-2{stroke-width:12px;}.cls-2,.cls-3{fill:#696972;}.cls-3{font-size:139px;font-family:MyriadPro-Regular, Myriad Pro;}.cls-3,.cls-4{stroke-width:5px;}</style></defs><title>umlComposition</title><path class="cls-1" d="M254.62,126.34c8.58-.4,21.06-.92,36.2-1.24,22.68-.49,28.26-.07,33.06.51,14.42,1.76,25.75,3.15,37.28,10.87,13.15,8.82,19.31,21,23.8,29.9a103.69,103.69,0,0,1,9,26.76c2,9.8,2.28,17.23,2.71,30.3.32,10,0,14.22-.07,27.07-.06,8.19-.06,20.24.33,35.13"/><rect class="cls-2" x="38.38" y="38.3" width="140.62" height="212.7" rx="12.24"/><rect class="cls-2" x="325.82" y="259.41" width="140.62" height="212.7" rx="12.24"/><path class="cls-2" d="M197.67,131l57.66,33.28a5.78,5.78,0,0,0,8.67-5V92.71a5.78,5.78,0,0,0-8.67-5L197.67,121A5.79,5.79,0,0,0,197.67,131Z"/><text class="cls-3" transform="translate(31.91 425.65) scale(1.03 1)">UML</text><line class="cls-4" x1="60" y1="83.5" x2="158" y2="83.5"/><line class="cls-4" x1="348" y1="304.5" x2="446" y2="304.5"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cls-1{fill:#d79400;}.cls-2{fill:#ffd55e;}.cls-3{font-size:209.75px;fill:#696972;font-family:MyriadPro-Regular, Myriad Pro;}</style></defs><title>umlProject</title><rect class="cls-1" x="25" y="40" width="173" height="64" rx="8.54"/><rect class="cls-2" x="15" y="94" width="470" height="351" rx="8.54"/><text class="cls-3" transform="translate(25 338.56) scale(1.13 1)">UML</text></svg>

After

Width:  |  Height:  |  Size: 496 B

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 895 B

View File

@@ -1,20 +1,17 @@
package com.thinkode.appthinker.models;
import java.io.Serializable;
/**
* Gère une composition d'un projet.
*
* @author V.BOULANGER
*/
public class Composition {
public class Composition implements Serializable {
public static int _compositionId = 0;
protected int _id;
protected String _name;
protected CompositionType _type;
public enum CompositionType {
UML_DIAGRAM
}
public Composition() {
_id = _compositionId++;
@@ -46,13 +43,4 @@ public class Composition {
public int getId() {
return _id;
}
/**
* Retourne le type de la composition.
*
* @return Le type de la composition.
*/
public CompositionType getType() {
return _type;
}
}

View File

@@ -6,6 +6,8 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* Gère un projet.
@@ -22,7 +24,7 @@ public class Project implements Serializable {
private String _version;
private String _designation;
private String _path;
private Composition _composition;
private List<Composition> _compositions;
/**
* Constructeur - Crée une instance de Projet.
@@ -30,28 +32,39 @@ public class Project implements Serializable {
public Project() {
_projectId++;
_id = _projectId;
_name = "Untitled project";
_name = "Untitled project " + _projectId;
_author = "Unknown";
_version = "0.0.1";
_designation = "AppThinker project.";
_path = null;
}
public void setComposition(Composition composition) {
_composition = composition;
}
public void removeComposition() {
_composition = null;
_compositions = new ArrayList<Composition>();
}
/**
* Récupère la composition associée au projet.
* Ajoute une composition au projet
*
* @return La composition associée au projet.
* @param composition
*/
public Composition getComposition() {
return this._composition;
public void addComposition(Composition composition) {
_compositions.add(composition);
}
/**
* Retire une composition du projet
*
* @param compositionListId
*/
public void removeComposition(int compositionListId) {
_compositions.remove(compositionListId);
}
/**
* Récupère les compositions inclues dans le projet.
*
* @return Les compositions inclues dans le projet.
*/
public List<Composition> getCompositions() {
return this._compositions;
}
/**
@@ -160,11 +173,11 @@ public class Project implements Serializable {
*/
public boolean saveProject() {
//Si le projet ne contient pas de path, on demande à l'enregistrer dans un emplacement
FileNameExtensionFilter fileFilter = new FileNameExtensionFilter("AppThinker.Application.Engine.AppThinker project", "appt");
FileNameExtensionFilter fileFilter = new FileNameExtensionFilter("AppThinker project", "appt");
String path = this.getPath();
if (path == null) {
JFileChooser dialog = new JFileChooser();
dialog.setDialogTitle("Save an AppThinker.Application.Engine.AppThinker project");
dialog.setDialogTitle("Save an AppThinker project");
dialog.setDialogType(JFileChooser.SAVE_DIALOG);
dialog.setFileFilter(fileFilter);
dialog.setAcceptAllFileFilterUsed(false);
@@ -204,11 +217,11 @@ public class Project implements Serializable {
*/
public boolean saveAsProject() {
//Enregistrer le projet sous un autre emplacement
FileNameExtensionFilter fileFilter = new FileNameExtensionFilter("AppThinker.Application.Engine.AppThinker project", "appt");
FileNameExtensionFilter fileFilter = new FileNameExtensionFilter("AppThinker project", "appt");
String path = this.getPath();
JFileChooser dialog = new JFileChooser();
dialog.setDialogTitle("Save an AppThinker.Application.Engine.AppThinker project");
dialog.setDialogTitle("Save an AppThinker project");
dialog.setDialogType(JFileChooser.SAVE_DIALOG);
dialog.setFileFilter(fileFilter);
dialog.setAcceptAllFileFilterUsed(false);

View File

@@ -16,8 +16,7 @@ public class UmlDiagram extends Composition {
private Class _mainClass = null;
public UmlDiagram() {
_type = CompositionType.UML_DIAGRAM;
_name = "Composition " + _compositionId + " (" + _type + ")";
_name = "UML Diagram " + _compositionId;
_classes = new ArrayList<Class>();
_links = new ArrayList<Link>();
}

View File

@@ -0,0 +1,165 @@
package com.thinkode.appthinker.views;
import com.thinkode.appthinker.AppThinker;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
public class CompositionWidget extends JTabbedPane implements ActionListener, CompositionListener, ChangeListener {
private ArrayList<String> _titlePans;
private ArrayList<String> _projectPans;
public CompositionWidget() {
this.addChangeListener(this);
_titlePans = new ArrayList<String>();
_projectPans = new ArrayList<String>();
}
/**
* Ajoute un nouvel onglet au composant contenant la composition à ajouter
*
* @param title
* @param compositionFrame
*/
public void addCompositionFrame(String title, String project, CompositionFrame compositionFrame) {
//Ajout du contenu de l'onglet
int tabInsert = this.getSelectedIndex() + 1;
//System.out.println(this.getTabCount());
compositionFrame.addCompositionListener(this);
//Si l'onglet n'existe pas encore, on le crée
int indexDuplicate = checkIfExist(title, project);
if (indexDuplicate == -1) {
//Insertion de l'onglet
_titlePans.add(tabInsert, title);
_projectPans.add(tabInsert, project);
this.insertTab(title, new ImageIcon(AppThinker.class.getResource("img/x16/umlComposition.png")), compositionFrame, "<html><b>" + title + "</b></html>", tabInsert);
} else tabInsert = indexDuplicate;
this.setSelectedIndex(tabInsert);
optimizeNames();
}
/**
* Vérifie que l'onglet à ajouter n'est pas déjà ouvert
*
* @param title
* @param project
* @return
*/
private int checkIfExist(String title, String project) {
for (int index = 0; index < this.getTabCount(); index++) {
if (title.equals(_titlePans.get(index)) && project.equals(_projectPans.get(index))) return index;
}
return -1;
}
/**
* Crée l'objet graphique du titre de l'onglet
*
* @return
*/
private JPanel createTitlePan(String title) {
JPanel titlePan = new JPanel();
titlePan.setOpaque(false);
titlePan.setLayout(new BorderLayout());
JLabel compositionIcon = new JLabel(new ImageIcon(AppThinker.class.getResource("img/x16/umlComposition.png")));
titlePan.add(compositionIcon, BorderLayout.WEST);
JLabel titleString = new JLabel(" " + title + " ");
titlePan.add(titleString, BorderLayout.CENTER);
JButton titleButton = new JButton(new ImageIcon(AppThinker.class.getResource("img/x16/closeTab.png")));
titleButton.setBorderPainted(false);
titleButton.setOpaque(false);
titleButton.setPreferredSize(new Dimension(20, 20));
titleButton.setToolTipText("<html>Close <b><i>" + title + "</i></b></html>");
titleButton.setBackground(new Color(105, 105, 114));
titleButton.addActionListener(this);
titlePan.add(titleButton, BorderLayout.EAST);
return titlePan;
}
/**
* Vérifie qu'il n'y ait pas 2 compositions ouvertes du même nom. Rajoute le nom de projet pour les différencier dans ce cas.
*
* @return
*/
private void optimizeNames() {
for (String title : _titlePans) {
ArrayList<Integer> occurence = new ArrayList<>();
for (int j = 0; j < this.getTabCount(); j++) {
if (_titlePans.get(j).equals(title)) occurence.add(j);
}
//La composition ouverte n'a pas de doublon
if (occurence.size() == 1) this.setTabComponentAt(occurence.get(0), createTitlePan(title));
//La composition ouverte a plusieurs doublons
else {
for (int index : occurence) {
this.setTabComponentAt(index, createTitlePan(title + " - " + _projectPans.get(index)));
}
}
}
}
/**
* Met à jour le titre de la composition modifiée
*
* @param projectName
* @param newName
*/
public void updateCompositionTitle(String projectName, String oldName, String newName) {
for (int i = 0; i < this.getTabCount(); i++) {
if (_titlePans.get(i).equals(oldName) && _projectPans.get(i).equals(projectName))
_titlePans.set(i, newName);
}
optimizeNames();
}
/**
* Supprime la composition du widget
*/
public void deleteCompositionFrame(String projectName, String composition) {
for (int i = 0; i < this.getTabCount(); i++) {
if (_titlePans.get(i).equals(composition) && _projectPans.get(i).equals(projectName)) {
_titlePans.remove(i);
_projectPans.remove(i);
this.remove(i);
}
}
optimizeNames();
}
//Evenements de la composition
@Override
public void statusEmitted(String status) {
/*setStatusMessage(status);*/
}
@Override
public void mousePositionUpdated(int mouseX, int mouseY) {
/*setPositionLabel(mouseX, mouseY);*/
}
@Override
public void elementSizeUpdated(int sizeX, int sizeY) {
/*setSizeLabel(sizeX, sizeY);*/
}
@Override
public void actionPerformed(ActionEvent e) {
JButton btn = (JButton) e.getSource();
_titlePans.remove(this.getSelectedIndex());
_projectPans.remove(this.getSelectedIndex());
this.remove(this.getSelectedIndex());
optimizeNames();
}
@Override
public void stateChanged(ChangeEvent e) {
//System.out.println("Onglet cliqué !");
}
}

View File

@@ -12,7 +12,7 @@ public class HomeFrame extends CompositionFrame {
private HomeFrameController _homeFrameController;
private JPanel _newProject;
private JPanel _newBlankProject;
private JPanel _newUmlProject;
private JPanel _openProject;
private JPanel _proposeIdeas;
@@ -72,21 +72,21 @@ public class HomeFrame extends CompositionFrame {
JPanel projectPanel = new JPanel();
projectPanel.setLayout(new BoxLayout(projectPanel, BoxLayout.Y_AXIS));
//--Bouton nouveau projet
_newProject = new JPanel();
_newProject.setLayout(new FlowLayout(FlowLayout.LEFT));
_newBlankProject = new JPanel();
_newBlankProject.setLayout(new FlowLayout(FlowLayout.LEFT));
JLabel imgNewProject = new JLabel(new ImageIcon(AppThinker.class.getResource("img/x32/newProject.png")));
_newProject.add(imgNewProject);
_newBlankProject.add(imgNewProject);
JLabel newProjectLabel = new JLabel("Create a blank project");
_newProject.setToolTipText("Create a new project without composition");
_newProject.add(newProjectLabel);
_newProject.addMouseListener(this);
projectPanel.add(_newProject);
_newBlankProject.setToolTipText("Create a new project without composition");
_newBlankProject.add(newProjectLabel);
_newBlankProject.addMouseListener(this);
projectPanel.add(_newBlankProject);
//--Bouton nouveau projet UML
_newUmlProject = new JPanel();
_newUmlProject.setLayout(new FlowLayout(FlowLayout.LEFT));
JLabel imgNewUmlProject = new JLabel(new ImageIcon(AppThinker.class.getResource("img/x32/newProject.png")));
_newUmlProject.add(imgNewUmlProject);
JLabel newUmlProjectLabel = new JLabel("Create a project with an Uml diagram");
JLabel newUmlProjectLabel = new JLabel("Create a UML project");
_newUmlProject.setToolTipText("Create a new project and initialize it with an UML diagram");
_newUmlProject.add(newUmlProjectLabel);
_newUmlProject.addMouseListener(this);
@@ -154,7 +154,6 @@ public class HomeFrame extends CompositionFrame {
//Panneau ne plus afficher
_dontShow = new JCheckBox("Do not show this home page at startup");
//System.out.println(_homeFrameController.isHomeAtStartup());
_dontShow.addMouseListener(this);
content.add(_dontShow, BorderLayout.SOUTH);
@@ -173,8 +172,8 @@ public class HomeFrame extends CompositionFrame {
Object obj = e.getSource();
if (obj instanceof JPanel) {
JPanel pan = (JPanel) obj;
if (pan == _newProject) _homeFrameController.startNewProject();
else if (pan == _newUmlProject) _homeFrameController.startNewProject();
if (pan == _newBlankProject) _homeFrameController.newBlankProject();
else if (pan == _newUmlProject) _homeFrameController.newUmlProject();
else if (pan == _openProject) {
FileNameExtensionFilter fileFilter = new FileNameExtensionFilter("AppThinker project", "appt");
JFileChooser dialog = new JFileChooser();

View File

@@ -14,7 +14,9 @@ import java.awt.event.ActionListener;
public class MenuBar extends JMenuBar {
private JMenu _fileMenu;
private JMenuItem _newProject;
private JMenu _newProject;
private JMenuItem _newBlankProject;
private JMenuItem _newUmlProject;
private JMenuItem _openProject;
private JMenuItem _saveProject;
private JMenuItem _saveAsProject;
@@ -36,14 +38,26 @@ public class MenuBar extends JMenuBar {
//Création de la barre menu
_fileMenu = new JMenu("File");
_newProject = new JMenuItem("New project");
_newProject = new JMenu("New");
_newProject.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/newProject.png")));
_newProject.addActionListener(new ActionListener() {
_newBlankProject = new JMenuItem("Blank project");
_newBlankProject.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/blankProject.png")));
_newBlankProject.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
_menuBarListener.newProjectClicked();
_menuBarListener.newBlankProjectClicked();
}
});
_newProject.add(_newBlankProject);
_newUmlProject = new JMenuItem("UML project");
_newUmlProject.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/umlProject.png")));
_newUmlProject.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
_menuBarListener.newUmlProjectClicked();
}
});
_newProject.add(_newUmlProject);
_fileMenu.add(_newProject);
_openProject = new JMenuItem("Open project");
_openProject.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/importProject.png")));
@@ -54,43 +68,6 @@ public class MenuBar extends JMenuBar {
}
});
_fileMenu.add(_openProject);
_saveProject = new JMenuItem("Save project");
_saveProject.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/saveProject.png")));
_saveProject.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
_menuBarListener.saveProjectClicked();
/*if (_window.getProject().saveProject())
_window.getStatusbar().setStatusMessage("The project has been saved.");
else _window.getStatusbar().setStatusMessage("An error occurred while saving the project.");*/
}
});
_fileMenu.add(_saveProject);
_saveAsProject = new JMenuItem("Save project as...");
_saveAsProject.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/saveAsProject.png")));
_saveAsProject.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
_menuBarListener.saveAsProjectClicked();
/*if (_window.getProject().saveAsProject())
_window.getStatusbar().setStatusMessage("The project has been saved.");
else _window.getStatusbar().setStatusMessage("An error occurred while saving the project.");*/
}
});
_fileMenu.add(_saveAsProject);
_closeProject = new JMenuItem("Close project");
_closeProject.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/closeProject.png")));
_closeProject.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
/*_window.closeProject();*/
_menuBarListener.closeProjectClicked();
}
});
_projectOptions = new JMenuItem("Project options");
_projectOptions.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/settings.png")));
_fileMenu.add(_projectOptions);
_fileMenu.add(_closeProject);
_quitMenu = new JMenuItem("Quit");
_quitMenu.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/quit.png")));
_quitMenu.addActionListener(new ActionListener() {
@@ -128,7 +105,6 @@ public class MenuBar extends JMenuBar {
_appMenu.add(_appChangelog);
this.add(_appMenu);
this.setProjectEnable(false);
}
public void addMenuBarListener(MenuBarListener listener) {
@@ -139,15 +115,4 @@ public class MenuBar extends JMenuBar {
_menuBarListener = null;
}
/**
* Active/Désactive les boutons relatifs au projet.
*
* @param enabled Le paramètre d'activation.
*/
public void setProjectEnable(boolean enabled) {
_saveProject.setEnabled(enabled);
_saveAsProject.setEnabled(enabled);
_projectOptions.setEnabled(enabled);
_closeProject.setEnabled(enabled);
}
}

View File

@@ -2,30 +2,20 @@ package com.thinkode.appthinker.views;
public interface MenuBarListener {
/**
* Evenement appelé lors d'un clic sur le bouton Nouveau Projet
* Evenement appelé lors d'un clic sur le bouton Nouveau Projet Vide
*/
void newProjectClicked();
void newBlankProjectClicked();
/**
* Evenement appelé lors d'un clic sur le bouton Nouveau Projet UML
*/
void newUmlProjectClicked();
/**
* Evenement appelé lors d'un clic sur le bouton Ouvrir un projet
*/
void openProjectClicked();
/**
* Evenement appelé lors d'un clic sur le bouton Sauvegarder Projet
*/
void saveProjectClicked();
/**
* Evenement appelé lors d'un clic sur le bouton Sauvegarder Sous Projet
*/
void saveAsProjectClicked();
/**
* Evenement appelé lors d'un clic sur le bouton Fermer Projet
*/
void closeProjectClicked();
/**
* Evenement appelé lors d'un clic sur le bouton Quitter
*/

View File

@@ -16,7 +16,7 @@ public class Splashscreen extends JFrame {
*/
public Splashscreen() {
this.setTitle("AppThinker - Starting");
this.setMinimumSize(new Dimension(600, 300));
this.setMinimumSize(new Dimension(600, 350));
Image img = null;
try {
img = ImageIO.read(AppThinker.class.getResource("/com/thinkode/appthinker/img/logoAppThinker.png"));
@@ -39,7 +39,7 @@ public class Splashscreen extends JFrame {
img = ImageIO.read(AppThinker.class.getResource("/com/thinkode/appthinker/img/splashscreen.png"));
} catch (Exception ex) {
}
g2.drawImage(img, 0, 0, 600, 300, this);
g2.drawImage(img, 0, 0, 600, 350, this);
/*Informations du logiciel*/
g2.setColor(new Color(63, 169, 245));
g2.setFont(new Font("Arial", Font.BOLD, 40));

View File

@@ -246,27 +246,6 @@ public class UmlToolbar extends JPanel {
this.setEnabled(false);
}
/**
* Verrouille/Déverrouille la barre d'outil.
*
* @param enabled Paramètre de verrouillage.
*/
public void setEnabled(boolean enabled) {
_select.setEnabled(enabled);
_edit.setEnabled(enabled);
_delete.setEnabled(enabled);
_copy.setEnabled(enabled);
_paste.setEnabled(enabled);
_undo.setEnabled(enabled);
_redo.setEnabled(enabled);
_newClass.setEnabled(enabled);
_newStrong.setEnabled(enabled);
_newWeak.setEnabled(enabled);
_newComposition.setEnabled(enabled);
_newAggregation.setEnabled(enabled);
_newInheritance.setEnabled(enabled);
}
public void addUmlToolbarListener(UmlToolbarListener atUmlToolbarListener) {
_atUmlToolbarListener = atUmlToolbarListener;
}

View File

@@ -2,6 +2,7 @@ package com.thinkode.appthinker.views;
import com.thinkode.appthinker.AppThinker;
import com.thinkode.appthinker.controllers.WindowController;
import com.thinkode.appthinker.models.Project;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import javax.imageio.ImageIO;
@@ -12,11 +13,12 @@ import java.awt.*;
/**
* Affiche une fenêtre du logiciel.
*/
public class Window extends JFrame implements MenuBarListener, CompositionListener {
public class Window extends JFrame implements MenuBarListener, WorkspaceListener {
private final MenuBar _menubar;
private final Statusbar _statusbar;
private CompositionFrame _composition;
private final Workspace _workspace;
private CompositionWidget _compositionWidget;
private WindowController _mainWindowController;
@@ -27,7 +29,7 @@ public class Window extends JFrame implements MenuBarListener, CompositionListen
//Paramétrage de la fenêtre
this.setTitle("AppThinker");
this.setExtendedState(JFrame.MAXIMIZED_BOTH);
this.setMinimumSize(new Dimension(750, 500));
this.setMinimumSize(new Dimension(1000, 500));
Image img;
try {
img = ImageIO.read(AppThinker.class.getResource("img/logoAppThinker.png"));
@@ -48,7 +50,15 @@ public class Window extends JFrame implements MenuBarListener, CompositionListen
//Ajout de la statusbar à la fenêtre
_statusbar = new Statusbar();
this.add(_statusbar, BorderLayout.SOUTH);
closeComposition();
//Ajout du Workspace à la fenêtre
_workspace = new Workspace();
_workspace.addWorkspaceListener(this);
this.add(_workspace, BorderLayout.WEST);
//Ajout du Widget de visualisation des compositions
_compositionWidget = new CompositionWidget();
this.add(_compositionWidget, BorderLayout.CENTER);
}
/**
@@ -60,14 +70,6 @@ public class Window extends JFrame implements MenuBarListener, CompositionListen
_mainWindowController = mainWindowController;
}
/**
* Crée un nouveau Projet.
*/
public void newProject() {
//Si un projet est ouvert, on le ferme d'abord
_mainWindowController.startNewProject();
}
/**
* Ouvre un projet existant dans la fenêtre.
*/
@@ -83,18 +85,6 @@ public class Window extends JFrame implements MenuBarListener, CompositionListen
}
}
/**
* Ferme le projet en cours.
*/
public void closeProject() {
this.setTitle("AppThinker");
this.getMenubar().setProjectEnable(false);
closeComposition();
setStatusMessage("The project has been closed.");
setFileMessage("No project opened.");
this.closeComposition();
}
/**
* Récupère la menubar contenue dans la fenêtre.
*
@@ -114,34 +104,26 @@ public class Window extends JFrame implements MenuBarListener, CompositionListen
}
/**
* Affiche une composition au centre de la fenêtre.
* Ajoute une composition dans le widget central.
*
* @param composition La composition à afficher.
*/
public void displayComposition(CompositionFrame composition) {
closeComposition();
//Ajout de la composition à la fenêtre
_composition = composition;
_composition.addCompositionListener(this);
this.add(_composition, BorderLayout.CENTER);
public void addCompositionFrame(String compositionName, String projectName, CompositionFrame composition) {
//Ajout de la composition au widget central
_compositionWidget.addCompositionFrame(compositionName, projectName, composition);
//Modification de la barre de statut
//String projectName = _mainWindowController.getProjectName();
//setFileMessage(projectName);
//Modification du titre et activation des fonctionnalités d'édition
//String projectPath = _mainWindowController.getProjectPath();
//this.setTitle((projectPath == null) ? "AppThinker - " + projectName + "*" : "AppThinker - " + projectName + " (" + projectPath + ")");
_menubar.setProjectEnable(true);
this.revalidate();
}
/**
* Retire la composition de la fenêtre.
* Affiche un message d'alerte
*/
public void closeComposition() {
if (_composition != null) this.remove(_composition);
public void showMessage(String message) {
JOptionPane.showMessageDialog(this, message);
}
public void setStatusMessage(String message) {
@@ -160,10 +142,88 @@ public class Window extends JFrame implements MenuBarListener, CompositionListen
_statusbar.setFileMessage(fileMessage);
}
//Evènements de la barre de menu (ATMenuBarListener)
/**
* Remet à jour le Workspace à l'aide des projets de la fenêtre
*
* @param projects
*/
public void refreshWorkspace(java.util.List<Project> projects) {
_workspace.refreshTree(projects);
}
/**
* Remet à jour le titre de la composition ouverte dans le CompositionWidget
*
* @param project
* @param oldName
* @param newName
*/
public void updateCompositionTitle(String project, String oldName, String newName) {
_compositionWidget.updateCompositionTitle(project, oldName, newName);
}
/**
* Supprime la composition du CompositionWidget
*/
public void deleteCompositionFrame(String project, String composition) {
_compositionWidget.deleteCompositionFrame(project, composition);
}
//Evenements du Workspace
@Override
public void newProjectClicked() {
_mainWindowController.startNewProject();
public void homePageClicked() {
_mainWindowController.showHomeFrame();
}
@Override
public void addUmlComposition(int projectListId) {
_mainWindowController.addUmlComposition(projectListId);
}
@Override
public void renameProject(int projectListId, String newName) {
_mainWindowController.renameProject(projectListId, newName);
}
@Override
public void saveProjectClicked(int projectListId) {
_mainWindowController.saveProject(projectListId);
}
@Override
public void saveAsProjectClicked(int projectListId) {
_mainWindowController.saveAsProject(projectListId);
}
@Override
public void deleteProject(int projectListId) {
_mainWindowController.deleteProject(projectListId);
}
@Override
public void renameComposition(int projectListId, int compositionListId, String newName) {
_mainWindowController.renameComposition(projectListId, compositionListId, newName);
}
@Override
public void deleteComposition(int projectListId, int compositionListId) {
_mainWindowController.deleteComposition(projectListId, compositionListId);
}
//Evènements de la barre de menu (MenuBarListener)
@Override
public void newBlankProjectClicked() {
_mainWindowController.newBlankProject();
}
@Override
public void compositionDoubleClick(int projectListId, int compositionListId) {
_mainWindowController.openComposition(projectListId, compositionListId);
}
@Override
public void newUmlProjectClicked() {
_mainWindowController.newUmlProject();
}
@Override
@@ -171,21 +231,6 @@ public class Window extends JFrame implements MenuBarListener, CompositionListen
openProject();
}
@Override
public void saveProjectClicked() {
System.out.println("Bouton sauvegarder projet cliqué");
}
@Override
public void saveAsProjectClicked() {
System.out.println("Bouton sauvegarder sous projet cliqué");
}
@Override
public void closeProjectClicked() {
_mainWindowController.closeProject();
}
@Override
public void quitClicked() {
_mainWindowController.exitApplication();
@@ -200,20 +245,4 @@ public class Window extends JFrame implements MenuBarListener, CompositionListen
public void checkUpdatesClicked() {
_mainWindowController.checkForUpdates();
}
//Evenements de la composition
@Override
public void statusEmitted(String status) {
setStatusMessage(status);
}
@Override
public void mousePositionUpdated(int mouseX, int mouseY) {
setPositionLabel(mouseX, mouseY);
}
@Override
public void elementSizeUpdated(int sizeX, int sizeY) {
setSizeLabel(sizeX, sizeY);
}
}

View File

@@ -0,0 +1,263 @@
package com.thinkode.appthinker.views;
import com.thinkode.appthinker.AppThinker;
import com.thinkode.appthinker.models.Composition;
import com.thinkode.appthinker.models.Project;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.*;
public class Workspace extends JPanel implements ActionListener, MouseListener, MouseMotionListener {
private final JPanel _actionPanel;
private final JPanel _homePage;
private final JPanel _newProject;
private JPanel _contentPanel;
private JTree _tree;
private JScrollPane _scrollPane;
private WorkspaceListener _listener;
private DefaultMutableTreeNode _root;
private JTextField _nameProject;
private JMenuItem _renameProject;
private JMenuItem _saveProject;
private JMenuItem _saveAsProject;
private JMenuItem _newUmlComposition;
private JMenuItem _deleteProject;
private JTextField _nameComposition;
private JMenuItem _renameComposition;
private JMenuItem _deleteComposition;
public Workspace() {
this.setLayout(new BorderLayout());
this.setPreferredSize(new Dimension(300, 10000));
_actionPanel = new JPanel();
_actionPanel.setLayout(new BorderLayout());
_actionPanel.setBackground(new Color(222, 222, 222));
Border panelBorder = BorderFactory.createLineBorder(new Color(105, 105, 114), 1);
_actionPanel.setBorder(panelBorder);
_homePage = new JPanel();
_homePage.setBackground(new Color(222, 222, 222));
_homePage.setLayout(new FlowLayout(FlowLayout.LEFT));
JLabel imgHome = new JLabel(new ImageIcon(AppThinker.class.getResource("img/x16/homePage.png")));
_homePage.add(imgHome);
_homePage.setToolTipText("Go to home page");
_homePage.addMouseListener(this);
_actionPanel.add(_homePage, BorderLayout.WEST);
_newProject = new JPanel();
_newProject.setBackground(new Color(222, 222, 222));
_newProject.setLayout(new FlowLayout(FlowLayout.LEFT));
JLabel imgNewProject = new JLabel(new ImageIcon(AppThinker.class.getResource("img/x16/newProject.png")));
_newProject.add(imgNewProject);
_newProject.setToolTipText("Create a new project");
_newProject.addMouseListener(this);
_actionPanel.add(_newProject, BorderLayout.EAST);
this.add(_actionPanel, BorderLayout.NORTH);
_scrollPane = new JScrollPane();
this.add(_scrollPane, BorderLayout.CENTER);
}
/**
* Crée l'arborescence des projets dans le Workspace
*/
public void refreshTree(java.util.List<Project> projects) {
//Suppression de la scrollbar
this.remove(_scrollPane);
//Aucun projet n'est ouvert, on affiche le message par défaut
if (projects.size() == 0) {
_contentPanel = new JPanel();
_contentPanel.setBackground(new Color(222, 222, 222));
JLabel lbl2 = new JLabel("No project is open. Click on + to add a project.");
_contentPanel.add(lbl2);
_scrollPane = new JScrollPane(_contentPanel);
}
//Au moins un projet est ouvert, on construit l'arborescence des projets
else {
_root = new DefaultMutableTreeNode("Opened projects");
for (Project proj : projects) {
DefaultMutableTreeNode project = new DefaultMutableTreeNode(proj.getName());
for (Composition comp : proj.getCompositions()) {
DefaultMutableTreeNode composition = new DefaultMutableTreeNode(comp.getName());
project.add(composition);
}
_root.add(project);
}
_tree = new JTree(_root);
_tree.expandPath(new TreePath(_root));
JPopupMenu projectContextMenu = new JPopupMenu("Project actions");
JMenuItem addMenu = new JMenu("New");
addMenu.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/newComposition.png")));
_newUmlComposition = new JMenuItem("UML Diagram");
_newUmlComposition.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/umlComposition.png")));
_newUmlComposition.addActionListener(this);
addMenu.add(_newUmlComposition);
projectContextMenu.add(addMenu);
projectContextMenu.add(new JSeparator());
_nameProject = new JTextField("");
_nameProject.setHorizontalAlignment(JLabel.CENTER);
projectContextMenu.add(_nameProject);
_renameProject = new JMenuItem("Rename");
_renameProject.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/rename.png")));
_renameProject.addActionListener(this);
projectContextMenu.add(_renameProject);
_saveProject = new JMenuItem("Save");
_saveProject.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/saveProject.png")));
_saveProject.addActionListener(this);
projectContextMenu.add(_saveProject);
_saveAsProject = new JMenuItem("Save As...");
_saveAsProject.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/saveAsProject.png")));
_saveAsProject.addActionListener(this);
projectContextMenu.add(_saveAsProject);
_deleteProject = new JMenuItem("Delete project");
_deleteProject.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/closeProject.png")));
_deleteProject.addActionListener(this);
projectContextMenu.add(_deleteProject);
_tree.add(projectContextMenu);
JPopupMenu compositionContextMenu = new JPopupMenu("Composition actions");
_nameComposition = new JTextField("");
_nameComposition.setHorizontalAlignment(JLabel.CENTER);
compositionContextMenu.add(_nameComposition);
_renameComposition = new JMenuItem("Rename");
_renameComposition.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/rename.png")));
_renameComposition.addActionListener(this);
compositionContextMenu.add(_renameComposition);
_deleteComposition = new JMenuItem("Delete composition");
_deleteComposition.setIcon(new ImageIcon(AppThinker.class.getResource("img/x16/deleteComposition.png")));
_deleteComposition.addActionListener(this);
compositionContextMenu.add(_deleteComposition);
_tree.add(compositionContextMenu);
MouseListener ml = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
int selRow = _tree.getRowForLocation(e.getX(), e.getY());
TreePath selPath = _tree.getPathForLocation(e.getX(), e.getY());
if (selRow != -1) {
int path = selPath.getPathCount();
if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON3) {
//Clic droit - Affichage des paramètres du projet/composition
_tree.setSelectionPath(selPath);
if (path == 2) {
projectContextMenu.show(_tree, e.getX(), e.getY());
_nameProject.setText(_tree.getSelectionPath().getLastPathComponent().toString());
} else {
compositionContextMenu.show(_tree, e.getX(), e.getY());
_nameComposition.setText(_tree.getSelectionPath().getLastPathComponent().toString());
}
} else if (e.getClickCount() == 2) {
if (path == 2) {
//Double-clic sur un projet
} else {
//Double clic sur une composition
DefaultMutableTreeNode selectedItem = (DefaultMutableTreeNode) _tree.getSelectionPath().getLastPathComponent();
int compositionId = selectedItem.getParent().getIndex(selectedItem);
int projectId = _root.getIndex(selectedItem.getParent());
_listener.compositionDoubleClick(projectId, compositionId);
}
}
}
}
};
_tree.addMouseListener(ml);
_tree.setRootVisible(false);
_scrollPane = new JScrollPane(_tree);
}
this.add(_scrollPane, BorderLayout.CENTER);
this.revalidate();
}
//Evenements du Workspace
public void addWorkspaceListener(WorkspaceListener listener) {
_listener = listener;
}
public void removeWorkspaceListener() {
_listener = null;
}
//Evenements souris
@Override
public void mouseClicked(MouseEvent e) {
Object obj = e.getSource();
if (obj instanceof JPanel) {
JPanel pan = (JPanel) obj;
if (pan == _homePage) _listener.homePageClicked();
else if (pan == _newProject) _listener.newBlankProjectClicked();
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
Object obj = e.getSource();
if (obj instanceof JPanel) {
JPanel pan = (JPanel) obj;
if (pan == _homePage || pan == _newProject) pan.setBackground(Color.GRAY);
}
}
@Override
public void mouseExited(MouseEvent e) {
Object obj = e.getSource();
if (obj instanceof JPanel) {
JPanel pan = (JPanel) obj;
if (pan == _homePage || pan == _newProject) pan.setBackground(new Color(222, 222, 222));
}
}
@Override
public void mouseDragged(MouseEvent e) {
}
@Override
public void mouseMoved(MouseEvent e) {
}
//Clic sur un JMenuItem
@Override
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj instanceof JMenuItem) {
JMenuItem item = (JMenuItem) obj;
DefaultMutableTreeNode selectedItem = (DefaultMutableTreeNode) _tree.getSelectionPath().getLastPathComponent();
if (item == _newUmlComposition) _listener.addUmlComposition(_root.getIndex(selectedItem));
else if (item == _renameProject) {
if (_nameProject.getText() != null && _nameProject.getText() != "") {
_listener.renameProject(_root.getIndex(selectedItem), _nameProject.getText());
}
} else if (item == _saveProject) {
_listener.saveProjectClicked(_root.getIndex(selectedItem));
} else if (item == _saveAsProject) {
_listener.saveAsProjectClicked(_root.getIndex(selectedItem));
} else if (item == _deleteProject) {
_listener.deleteProject(_root.getIndex(selectedItem));
} else if (item == _renameComposition) {
if (_nameComposition.getText() != null && _nameComposition.getText() != "") {
_listener.renameComposition(_root.getIndex(selectedItem.getParent()), selectedItem.getParent().getIndex(selectedItem), _nameComposition.getText());
}
} else if (item == _deleteComposition) {
int compositionId = selectedItem.getParent().getIndex(selectedItem);
int projectId = _root.getIndex(selectedItem.getParent());
_listener.deleteComposition(projectId, compositionId);
}
}
}
}

View File

@@ -0,0 +1,54 @@
package com.thinkode.appthinker.views;
public interface WorkspaceListener {
/**
* Clic sur le bouton de la page d'accueil
*/
void homePageClicked();
/**
* Clic sur le bouton d'ajout d'un nouveau projet vide
*/
void newBlankProjectClicked();
/**
* Ouverture d'une composition
*/
void compositionDoubleClick(int projectListId, int compositionListId);
/**
* Ajoute une composition UML à un projet
*/
void addUmlComposition(int projectListId);
/**
* Renomme le projet sélectionné
*/
void renameProject(int projectListId, String newName);
/**
* Sauvegarde le projet
*/
void saveProjectClicked(int projectListId);
/**
* Sauvegarde le projet sous
*/
void saveAsProjectClicked(int projectListId);
/**
* Supprime un projet via le menu contextuel Projet
*/
void deleteProject(int projectListId);
/**
* Renomme la composition d'un projet
*/
void renameComposition(int projectListId, int compositionListId, String newName);
/**
* Supprime une composition d'un projet via le menu contextuel Composition
*/
void deleteComposition(int projectListId, int compositionListId);
}