Messages
du sujet
Visualisateur 2D |
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
24 mars 2007 à 23:14
Bonjour,
J'aimerai créer une classe qui permet de visualiser, dans un rectangle 2D,le schéma du logement (gauche) et le tableau des équipements (droite)
Le schéma et le tableau contenu dans le rectangle 2D se mettra à jour en temps réél
voir le sujet de la discution :
http://www.developpez.net/forums/showthread.php?t=294018
Merci de m'aiguiller pour que je puisse créer cette classe dans la même philosophie de codage que sweet home.
Je ne sais pas trop par où commencer et quelles méthodes utiliser?
Les seul action sur ce visualisateur sera un zoom (par la suite).
le visuallisateur se trouvera en lieu et place du schéma 3d de sweet Home
Merci pour votre aide
|
Manu
Ville : Paris / France
Membre depuis : 29 avr. 2003
Messages : 394
|
25 mars 2007 à 19:46
Je pense qu'il faut que vous définissiez d'abord le modèle des données que vous voulez visualiser dans le tableau comme dans le schéma, de façon similaire à ce que font les classes Home, PieceOfFurniture ou Wall du package com.eteks.sweethome3d.model.
D'après vos explications (corrigez-moi si je me trompe), votre programme doit manipuler une fiche de manoeuvre composé d'actions. Créez donc une classe FicheManoeuvre qui contiendra une collection d'objets de classe ActionManoeuvre, un peu comme la classe Home mémorise un ensemble d'objets Wall.
Ensuite, créez des classes de vue qui permettront de visualiser une fiche de manoeuvre soit sous forme d'un tableau Swing, soit sous forme d'un dessin en 2D. Appelez-les, par exemple :
- TableauFicheManoeuvre pour le tableau qui sera alors une sous-classe de JTable (comme FurnitureTable dans Sweet Home 3D)
- ComposantFicheManoeuvre pour le dessin de la fiche qui sera une sous-classe de JComponent (comme PlanComponent)
Dans la classe TableauFicheManoeuvre, visualisez une action par ligne en créant un TableModel qui adaptera les données des actions aux colonnes du tableau (inspirez-vous de la section "Conception de la classe du tableau" pages 144 et suivantes)
Dans la classe ComposantFicheManoeuvre, dessinez ces actions en y redéfinissant la méthode paintComponent (inspirez-vous de la section "Création du composant du plan" pages 266 et suivantes)
Pour visualiser vos deux composants, créez par exemple une classe FenetreFicheManoeuvre qui dérivera de JFrame et qui contiendra une instance de JSplitPane avec des objets TableauFicheManoeuvre et ComposantFicheManoeuvre à gauche et à droite.
Pour tester le tout, créez dans un premier temps une instance de FicheManoeuvre avec des objets ActionManoeuvre par défaut et visualisez cette instance de fiche dans une fenêtre FenetreFicheManoeuvre.
Une fois que tout ceci marchera, vous pourrez alors essayer de vous attaquer à la modification de la liste des actions avec le pattern MVC, mais chaque chose en son temps... ;-)
J'espère que ma réponse a pu vous aider concrètement
--- Manu (moderator/modérateur)
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
26 mars 2007 à 17:57
Effectivement, ça m'aide beaucoup :)
Par contre, je ne vois pas trop pourquoi re-créer un tableau étant donné que je veux visualiser le tableau existant(tableau des equipements du logemement par analogie).De même pour le dessin.
Je pensais utiliser les classes déjà créer (HomePieceOfFurniture et Home) et de visusaliser le tout
merci pour votre aide...
|
Manu
Ville : Paris / France
Membre depuis : 29 avr. 2003
Messages : 394
|
26 mars 2007 à 21:16
La question n'est pas de recréer des classes mais plutôt de créer des classes dont le nom correspond aux concepts que tu manipules dans ton programme...
Si tu veux repartir de Sweet Home 3D dans sa version actuelle, tu peux toujours renommer chaque classe avec le menu Refactor>Rename... d'Eclipse après l'avoir sélectionné. --- Manu (moderator/modérateur)
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
26 mars 2007 à 22:58
Ok alors les classes cités ci-dessus fonctionne.
J'ai déjà réaliser la base du logiciel... en m'inspirants des classes de sweet home 3d
Par contre mon problème est d'intancier le tableau et le dessin et que c'est composant soit modifier en temps réel lorsque j'ajoute par exemple un meuble au logement par copier glisser
tu trouveras dans le lien suivant le résultat final souhaité
http://www.hiboox.com/image.php?img=f59c68a.png
La partie que je souhaite réaliser est la partie du bas à droite
c'est là que mon visualisateur sera situé
Mon problème : réaliser le visualisateur en utilisant les classes déjà utilisés (furnitureTable, PlanCompoment,...)et que la moindre modification du dessin (du logement) soit modifier aussi dans le visualisateur
Un peu comme dans Adobe Photoshop(visualisateur en haut à droite)
j'espère avoir était explicite.
merci du temps que tu me consacres... c'est vraiment sympa et je sais que ce n'est pas évident ... surtout de me comprendre ;)
Merci beaucoup
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
29 mars 2007 à 19:44
J'ai un peu avancé sur le sujet
Voici ma classe actuelle
[edit par pingoui le 05/04/07]suppression du code pour ne pas surcharger la discution et la bdd. Voir code plus loin dans la discution
Par contre, je bloque sur la copie de instance de planComponent.
je ne vois toujours pas comment visualiser en direct la construction du mur dans le JCompoment du haut (normal) ET le visualisateur dans bas!
Merci beaucoup pour ton aide
A charge de revanche... mon domaine proféssionnel est l'electricité... si un jour tu as besoin d'aide, n'hésites pas ;)
[Suggestion du modérateur suite à l'édition du message par pingoui : ne t'inquiètes pas pour la base de données, on n'est pas à quelques caractères près !]
|
Manu
Ville : Paris / France
Membre depuis : 29 avr. 2003
Messages : 394
|
29 mars 2007 à 22:55
> je ne vois toujours pas comment visualiser en direct la construction du mur
> dans le JCompoment du haut (normal) ET le visualisateur dans bas!
Si je comprends bien, tu voudrais que toute modification dans le composant du haut provoque une mise à jour dans le composant du bas. Il faut que tu mettes en place un listener sur ton modèle qui permettra à ces deux composants d'être notifiés quand le modèle aura subi des modifications, afin qu'ils se redessinent avec un appel à repaint par exemple. Pour mettre en place ces listeners, essaie d'appliquer l'architecture MVC. Je te conseille donc de relire le chapitre 6 à ce sujet, puis éventuellement le chapitre 8.
> si un jour tu as besoin d'aide, n'hésites pas ;)
Sait-on jamais ;-) --- Manu (moderator/modérateur)
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
31 mars 2007 à 20:22
> Si je comprends bien, tu voudrais que toute modification dans le composant du haut provoque une mise à jour dans le composant du bas.
C'est exactement ce que je souhaite réaliser
> Il faut que tu mettes en place un listener sur ton modèle qui permettra à ces deux composants d'être notifiés quand le modèle aura subi des modifications, afin qu'ils se redessinent avec un appel à repaint par exemple.
C'est là où je pêche . C'est la page blanche :(
>Pour mettre en place ces listeners, essaie d'appliquer l'architecture MVC. Je te conseille donc de relire le chapitre 6 à ce sujet, puis éventuellement le chapitre 8.
je viens de relire ces 2 chapitres et ne vois pas comment faire.
Malgrès, mes nombreuses lectures, je suis toujours bloqué .... Y a de quoi être découragé :(
Si j'ai bien suivi le livre, il existe déjà les listeners (HomeListener avec HomeEvent et WallListener avec WallEvent)
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
4 avr. 2007 à 18:34
Salut Manu,
Peux tu m'orienter sur les listeners à utiliser et comment les utilisier à bon essient dans le model MVC
J'ai fait d'autre progrès sur mon programme mais je reste néanmoins bloqué sur cette partie
Merci beaucoup.
|
Manu
Ville : Paris / France
Membre depuis : 29 avr. 2003
Messages : 394
|
4 avr. 2007 à 23:58
> Peux tu m'orienter sur les listeners à utiliser et comment les utilisier à bon essient dans le model MVC
Dans la version actuelle de Sweet Home 3D, quand un mur est modifié dans un objet Home, un événement de type WallEvent est émis vers tous les listeners qui se sont enregistrés auprès de ce logement avec la méthode addHomeListener.
C'est en implémentant un listener de type WallListener que la vue 3D est mise à jour à chaque modification dans le plan (voir page 343 où je découvre à l'instant une nouvelle coquille : l'instruction home.addWallListener(new WallListener() { [...] }); a été dupliquée !).
L'implémentation de ton WallListener pour la vue en bas est probablement plus simple car il doit suffire d'appeler repaint. --- Manu (moderator/modérateur)
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
5 avr. 2007 à 18:54
Merci beaucoup !!! Je viens enfin de voir une lueur sur ces listeners!
Etant donnée, que j'essaye de garder le niveau nécessaire pour réaliser mon programme, je ne me suis pas attarder sur la classe HomeCompoment3D... je ne comprenais donc pas comment fonctionné le listener!
Moi qui sort d'une réunion pourri... voilà un grand espoir qui souvre devant moi ;)
Bref ! :D
Tu trouveras ci dessous ma classe problématique.
Un code vaut mieux que cent mille discours
Ne sachant pas trop comment modifier les méthodes addHomeListeners, addWall et updateWall... je les aie laissé comme ça.
Dans mon programme la classe Home = Slip
[edit par pingoui le 05/04/07]
suppression du code pour ne pas surcharger la discution. Eh oui, je suis un maniaque de l'octet en plus ;)
voir code ci-dessous
[/edit]
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
6 avr. 2007 à 18:05
Voilà les dernières évolutions du code
Il me reste plus qu'a dessiner... et là c'est moins évident pour moi
Encore merci pour ton aide
[edit par pingoui le 17/04/07]
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
11 avr. 2007 à 18:20
Salut,
mes listeners ont l'air de fonctionner correctement. j'ai insérer des system.out.print() pour vérifier le fonctionnement
Il me reste désormais à modifier les méthodes addLine, updateLine et deleteLine
pour dessiner le schéma dans le visualisateur
Je suis partie de rien et me voilà presque au bout du chemin sur ce sujet ( enfin j'espère! ) Merci pour ton aide
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
13 avr. 2007 à 19:39
Je viens de relire le chapitre 9 complétement même si c'est un niveau trop élevé pour ma part mais en vain :(
Je n'arrive pas à trouvé un indice pour ajouter , mettre à jour et supprimer un mur
Je pensais faire une classe interne pour déssiner les murs mais je ne sais quoi mettre dedans :(
C'est un peu la page blanche... je ne sais vraiment pas quoi faire pour réaliser mon projet
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
17 avr. 2007 à 18:28
Hello, :)
Je suis toujours dans le flou mais je cherche toujours comment faire en faisant différents essai...
voici la dernière version...même s'il n'y a pas grand chose à tes yeux... mais pour moi, ca veux dire beaucoup ( ça me rappel un chanson)
@SuppressWarnings("serial")
public class SlipViewerComponent extends JComponent{
private static final int WIDTHRECT = 500;//Largeur du cadre
private static final int HEIGHTRECT = 200;//Hauteur du cadre
public SlipViewerComponent(Slip slip){
// Rendre le composant Opaque
setOpaque(true);
//Modification des propriétés par défaut du composant
setAutoscrolls(true);
addSlipListeners(slip);
}
private void addSlipListeners(final Slip slip) {
slip.addLineListener(new LineListener() {
public void lineChanged(LineEvent ev) {
Line line = ev.getLine();
switch (ev.getType()) {
case ADD :
addLine( line, slip);
break;
case UPDATE :
updateLine(line);
break;
case DELETE :
deleteLine(line);
break;
}
}
});
}
private void addLine( Line line, Slip slip) {
float [][] linePoints = line.getPoints();
System.out.println("ajout de ligne aux points :"+linePoints);
}
private void updateLine(Line line) {
if (line.getLineAtStart() != null) {
System.out.println("mise à jour point x1");
//this.homeObjects.get(line.getLineAtStart()).update();
}
if (line.getLineAtEnd() != null) {
System.out.println("mise à jour point x2");
//this.homeObjects.get(line.getLineAtEnd()).update();
}
}
private void deleteLine(Line line) {
System.out.println("suppression de la ligne");
}
/**
* Dessine un composant
*/
@Override
protected void paintComponent(Graphics g) {
//Création d'une copie du contexte graphique
Graphics2D g2D = (Graphics2D)g.create();
//dessin du fond
paintBackground(g2D);
//Dessin des cadres
paintFrame(g2D);
paintDrawingFrame(g2D);
paintTableFrame(g2D);
//libération des ressources associées à l'objet Graphics2D
g2D.dispose();
}
...
|
Manu
Ville : Paris / France
Membre depuis : 29 avr. 2003
Messages : 394
|
19 avr. 2007 à 11:06
D'après l'image du résultat que tu veux obtenir http://www.hiboox.com/image.php?img=f59c68a.png , j'ai l'impression que ton composant SlipViewerComponent en bas à droite n'est en fait qu'un assemblage du tableau et du plan.
C'est voulu ou le composant SlipViewerComponent est censé affiché autre chose ? --- Manu (moderator/modérateur)
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
20 avr. 2007 à 07:02
Salut
> D'après l'image du résultat que tu veux obtenir http://www.hiboox.com/image.php?img=f59c68a.png , j'ai l'impression que ton composant SlipViewerComponent en bas à droite n'est en fait qu'un assemblage du tableau et du plan.
Effectivement c'est un assemblage du tableau et du plan
> C'est voulu ou le composant SlipViewerComponent est censé affiché autre chose ?
le composant SlipViewerComponent dessine aussi le cartouche du plan. Il recupérér des informations sur le projet(titre, autres information etc...
Pour bien faire je vais essayer de ramener le résultat final souhaité. JE ferai un scan.
Le but étant de mettre en place les composants dans l'état final, le visualiser dans le fenetre du bas et par la suite d'imprimer le composant
merci pour ton aide
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
22 avr. 2007 à 14:20
Salut,
Voici un peu plus d'information sur mon petit projet perso.
Le but du logiciel est de réalisé des fiches de manoeuvre
Une fiche vierge:
http://www.mezimages.com/up/04/46230-ficheVierge.JPG
Une fiche remplie:
http://www.mezimages.com/up/04/46243-ficheRemplie.JPG
Je ne rentre pas plus dans le détails mais le but étant de réaliser une fiche de manoeuvre comme ci-dessus.
Les équipements (surligné en rose) dans le tableau à droite correspondent a unb composants sur le schéma à gauche.
Comme dans sweet Home, les informations (tableau) sur les meubles correspondent aux meubles insérés dans le Home
Voilà ce que je souhaite réalisé.
|
Manu
Ville : Paris / France
Membre depuis : 29 avr. 2003
Messages : 394
|
11 mai 2007 à 21:59
J'ai l'impression que votre composant SlipViewerComponent va surtout ressembler à la classe PlanComponent, sauf que vous y dessinerez de façon différente. A vous de voir comment vous pouvez factoriser une partie du code pour éviter de copier-coller inutilement le code de dessin du plan. --- Manu (moderator/modérateur)
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
12 mai 2007 à 13:09
Salut,
Je suis désolé mais c'est exactement là où j'ai un probleme.
Je ne vois pas comment factoriser une partie du code pour eviter les copier coller
C'est exactement là où je pêche
|
Manu
Ville : Paris / France
Membre depuis : 29 avr. 2003
Messages : 394
|
12 mai 2007 à 15:12
> Je ne vois pas comment factoriser une partie du code pour eviter les copier coller
Faites des copier-coller dans un premier temps. Ca vous permettra au moins d'obtenir un résultat concret.
Vous verrez ensuite les parties de code qui se ressemblent ce qui vous permettra de les factoriser. --- Manu (moderator/modérateur)
|
pingoui
Membre depuis : 24 mars 2007
Messages : 20
|
13 mai 2007 à 09:38
Ok merci pour le conseil
Je vais regarder ça
|
pingoui38
Ville : Levallois Perret
Membre depuis : 10 août 2007
Messages : 25
|
10 août 2007 à 13:57
Bonjour,
J'ai ajouter paintContent à SlipViewerComponent mais je ne sais pas comment lui passer les coordonnées récuperer avec mon listener (SlipListeners)
@SuppressWarnings("serial")
public class SlipViewerComponent extends JComponent{
private static final int WIDTHRECT = 500;//Largeur du cadre
private static final int HEIGHTRECT = 200;//Hauteur du cadre
private float scale = 0.5f;//Echelle par défaut
public SlipViewerComponent(Slip slip){
// Rendre le composant Opaque
setOpaque(true);
//Modification des propriétés par défaut du composant
setAutoscrolls(true);
addSlipListeners(slip);
}
private void addSlipListeners(final Slip slip) {
slip.addLineListener(new LineListener() {
public void lineChanged(LineEvent ev) {
Line line = ev.getLine();
switch (ev.getType()) {
case ADD :
addLine( line, slip);
break;
case UPDATE :
updateLine(line);
break;
case DELETE :
deleteLine(line);
break;
}
}
});
}
private void addLine( Line line, Slip slip) {
float [][] linePoints = line.getPoints();
System.out.println("ajout de ligne aux points :"+linePoints);
}
private void updateLine(Line line) {
if (line.getLineAtStart() != null) {
System.out.println("mise à jour point x1");
//this.homeObjects.get(line.getLineAtStart()).update();
}
if (line.getLineAtEnd() != null) {
System.out.println("mise à jour point x2");
//this.homeObjects.get(line.getLineAtEnd()).update();
}
}
private void deleteLine(Line line) {
System.out.println("suppression de la ligne");
}
/**
* Dessine un composant
*/
@Override
protected void paintComponent(Graphics g) {
//Création d'une copie du contexte graphique
Graphics2D g2D = (Graphics2D)g.create();
//dessin du fond
paintBackground(g2D);
//Dessin des cadres
paintFrame(g2D);
paintDrawingFrame(g2D);
paintTableFrame(g2D);
//libération des ressources associées à l'objet Graphics2D
g2D.dispose();
}
/**
* dessine le fond du composant s'il est opaque
*/
private void paintBackground(Graphics2D g2D) {
if (isOpaque()) {
//Récupération de la couleur de fond d'une fenêtre
//dans le Look and feel
Color backgroundColor = UIManager.getColor("window");
//remplissage du composant avec de la couleur de fond
g2D.setColor(backgroundColor);
g2D.fillRect(0, 0, getWidth(), getHeight());
}
}
/**
* dessine le cadre de la fiche
*/
private void paintFrame(Graphics2D g2D) {
//couleur du rectangle
g2D.setColor(Color.BLACK);
//dessine un rectangle
g2D.drawRect(((this.getSize().width- WIDTHRECT)/2),((this.getSize().height-HEIGHTRECT)/2),WIDTHRECT,HEIGHTRECT);
}
/**
* dessine le cadre de la partie schéma
*/
private void paintDrawingFrame(Graphics2D g2D) {
//couleur du rectangle
g2D.setColor(Color.BLACK);
//dessine un rectangle
g2D.drawRect(((this.getSize().width- WIDTHRECT)/2),((this.getSize().height-HEIGHTRECT)/2),WIDTHRECT/2,HEIGHTRECT);
}
/**
* dessine le cadre de la partie schéma
*/
private void paintTableFrame(Graphics2D g2D) {
//couleur du rectangle
g2D.setColor(Color.BLACK);
//dessine un rectangle
g2D.drawRect(((this.getSize().width- WIDTHRECT)/2)+(WIDTHRECT/2),((this.getSize().height-HEIGHTRECT)/2),WIDTHRECT/2,HEIGHTRECT);
}
/**
* Dessine les trait du schéma et le contour des traits selectionnées
*/
private void paintContent(Graphics2D g2D) {
//Récuparation de l'aire à dessiner
Shape linesArea = getLinesArea(this.slip.getLines());
//Remplissage des trait
g2D.fill(linesArea);
Stroke selectionStroke = new BasicStroke(6 / this.scale,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g2D.setStroke(selectionStroke);
List<Object> selectedItems = this.slip.getSelectedItems();
for (Object item : selectedItems) {
if (item instanceof Line) {
g2D.draw(linePoints);
}
}
// Dessin du contour de la surface des traits
g2D.setPaint(getForeground());
g2D.setStroke(new BasicStroke(2f / this.scale));
g2D.draw(linesArea);
}
}
J'avoue être limite avec mes faibles connaissances...
Je vous serai très reconnaissant de me guider
Merci beaucoup
|