France
Joined: May 4, 2010
Post Count: 16
Status:
Offline
Re: quelques besoins d'aide
Et ton entreprise mène ce projet juste par philanthropie !
Effectivement
Tu verras à l'usage que ma politique de développement est de restreindre l'accès public le plus souvent possible, car une classe ou une méthode public = une API à maintenir.
Bah, c'est pas plus à maintenir parce que c'est public que si ça ne l'est pas… Et de toute façon, tant qu'on ne tourne pas dans une vm avec politique de sécurité accrue, on peut faire un singleton, rendre ses méthodes publiques, et déléguer des appels static d'une classe utilitaire vers ce singleton. Mais c'est chiant(à maintenir)…
France
Joined: Nov 7, 2005
Post Count: 9426
Status:
Offline
Re: quelques besoins d'aide
Bah, c'est pas plus à maintenir parce que c'est public que si ça ne l'est pas…
Ben si, puisqu'une méthode ou une classe public c'est une API que d'autres projets comme le tien peuvent utiliser (et tu n'es pas le seul ;-). On ne peut plus la supprimer, y ajouter des paramètres, etc... sans casser la compatibilité ascendante. Il faut donc réfléchir encore plus avant de fixer sa signature "dans le marbre". Par contre, si une méthode privée t'intéresse, tu la recopies et je gardes la liberté de la faire évoluer plus tard sans te gêner.
----------------------------------------
Emmanuel Puybaret, Sweet Home 3D creator
France
Joined: Nov 7, 2005
Post Count: 9426
Status:
Offline
Re: quelques besoins d'aide
Dans le constructeur d'une sous-classe de PluginAction, je viens d'essayer de remplacer à la volée une instance de HomePieceOfFurniture par une instance d'une sous-classe public MyPieceOfFurniture appartenant au plug-in. Ca donne ça:
getHome().addFurnitureListener(new CollectionListener<HomePieceOfFurniture>() { public void collectionChanged(final CollectionEvent<HomePieceOfFurniture> ev) { if (ev.getType() == CollectionEvent.Type.ADD) { final Home home = (Home)ev.getSource(); home.removeFurnitureListener(this);
// Remplacement du meuble par une autre instance d'une sous-classe final MyPieceOfFurniture myPiece = new MyPieceOfFurniture(ev.getItem()); home.addPieceOfFurniture(myPiece, ev.getIndex());
home.addFurnitureListener(this);
// Suppression du meuble précédemment ajouté EventQueue.invokeLater(new Runnable() { public void run() { home.deletePieceOfFurniture(ev.getItem()); List<Selectable> selectedItems = new ArrayList<Selectable>(home.getSelectedItems()); selectedItems.add(myPiece); home.setSelectedItems(selectedItems); } }); } } });
Ca marche sur le moment, mais comme je le pressentais, le fichier sh3d qui contient des instances de MyPieceOfFurniture ne peut plus être lu après par Sweet Home 3D, parce que la classe MyPieceOfFurniture n'appartient pas au classpath de Sweet Home 3D. Cette classe n'est accessible que du plug-in et la lecture d'un fichier SH3D ne se fait pas dans le plug-in.
Si tu veux toujours continuer tes développements sous la forme d'un plug-in, je te conseille d'utiliser plutôt les méthodes setVisualProperty et getVisualProperty de la classe Home. Une "property value" peut être n'importe quelle instance d'une classe accessible dans Sweet Home 3D ; par exemple, un instance de HashMap dans laquelle tu stockes les valeurs supplémentaires dont tu as besoin pour chaque meuble (tu peux utiliser une instance de HomePieceOfFurniture comme clé de ta map). Ca n'est pas super génial, mais ça marche sans problème et je m'en sers dans le plug-in de rendu avancé pour stocker les valeurs saisies par l'utilisateur dans la boîte de dialogue.
----------------------------------------
Emmanuel Puybaret, Sweet Home 3D creator
France
Joined: May 4, 2010
Post Count: 16
Status:
Offline
Re: quelques besoins d'aide
Je viens de voir le EventQueue, je ne connaissais pas ; ça m'a permis de corriger un bug (que j'ai découvert en même temps), et donc ai je bien compris ? De ce que j'ai compris du bug, en AWT, les déplacements d'un objet peuvent être rendus dans des threads différents. Ce qui fait des race conditions : La solution que j'ai trouvée a été de déporter les mises à jour du modèle dans un Runnable placé dans l'EventQueue . ( au départ, l'idée était surtout de réduire la charge CPU en mutualisant les mises à jour, mais ça a corrigé un bug en même temps )
Sinon, en supprimant le
home.removeFurnitureListener(this);
et en le remplaçant par un affichage sur stdout, je vois que les objets qui sont créés sont :
interception of item com.eteks.sweethome3d.model.HomePieceOfFurniture@256f8834 creation interception of item com.eteks.sweethome3d.model.HomePieceOfFurniture@6c28ca1c creation loading file /home/guillaume/pastelGrid.xml interception of item lelouet.sh3d.plugins.sweetDatacenter.model.GRack@64d1afd3 creation interception of item lelouet.sh3d.plugins.sweetDatacenter.model.GServer@3bea817f creation interception of item lelouet.sh3d.plugins.sweetDatacenter.model.GServer@42d134d0 creation interception of item lelouet.sh3d.plugins.sweetDatacenter.model.GServer@25fe4d40 creation
Je trouve facilement comment filtrer pour laisser passer les ajouts d'éléments rack et model, mais par la suite je voudrais convertir les "HomePieceOfFurniture" en "GRack" ou "GServer", selon la catégorie du modèle. Est il alors possible de récupérer, à partir d'une HomePieceOfFurniture la catégorie de son modèle ?
Concernant la création d'objets dans sh3d, je compte utiliser une factory ( http://code.google.com/p/lelouettests/source/...odel/GElementFactory.java ) crée dans le plugin et ajoutée au listener, ce qui devrait à mon avis supprimer le problème du classloader (puisque l'objet factory est atteignable et connait son class loader) Est ce un raisonnement correct ?
France
Joined: Nov 7, 2005
Post Count: 9426
Status:
Offline
Re: quelques besoins d'aide
Tu as plus ou moins bien compris le principe de l'EventQueue. invokeLater diffère l'exécution du Runnable en paramètre dans l'Event Dispatch Thread qui gère les événements et le dessin à l'écran. Quand on fait appel à invokeLater alors qu'on est déjà dans l'EDT, le Runnable sera exécuté une fois que le traitement de l'événement courant est terminé. C'est le cas ici, et je m'en suis servi car la suppression du meuble juste après son ajout provoquait un bug dans le tableau des meubles. En différant la suppression, ça passait mieux mais ça pourrait désynchroniser certains traitements.
La factory ne changera pas le problème du classpath, puisque la factory est une classe qui est gérée elle aussi par le classloader du plug-in. Mais je ne connais pas ta stratégie ; tant que tu ne veux tu pas relire tes objets après les avoir enregistrés, tes sous-classes ne poseront pas de problème.
Pour gérer tes catégories d'objets, tu peux peut-être utilisé le champ "description" dont la valeur est lue dans les fichiers .properties des meubles avec une clé description#n et que l'on retrouve dans les classes CatalogPieceOfFurniture et HomePieceOfFuniture. Dans les faits, ce champ n'est pas utilisé dans la version actuelle de Sweet Home 3D donc tu peux en faire ce que tu veux.
----------------------------------------
Emmanuel Puybaret, Sweet Home 3D creator
France
Joined: May 4, 2010
Post Count: 16
Status:
Offline
Re: quelques besoins d'aide
Salut.
J'ai une nouvelle question : est il possible de changer le modèle graphique associé à un élément ? Exemple, si je passe d'un modèle 1U à un modèle2U, et que j'ai des modèles par défaut différents selon les U, il faudrait que le serveur change de peau.
Et une autre question : Puis je ajouter un JFrame/JPanel dans la fenêtre principale, dans un plugin ? Pour l'instant je l'ajoute dans une fenêtre en plus (avec bouton afficher/masquer), mais je préfèrerais l'intégrer à la fenetre standarde.
France
Joined: Nov 7, 2005
Post Count: 9426
Status:
Offline
Re: quelques besoins d'aide
Ca n'est pas possible de changer le modèle 3D associé à un meuble.
Ajouter une JFrame à une fenêtre est impossible puisque une instance de JFrame est une fenêtre, mais vous pouvez ajouter un JPanel à la fenêtre principale. Pour la retrouver, utilisez la méthode getFrames et explorez la hiérarchie des composants enfants pour retrouver le container où vous voulez ajouter votre panneau. C'est assez bidouille mais ça marchera.
----------------------------------------
Emmanuel Puybaret, Sweet Home 3D creator