IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants Java Discussion :

Place des composants dans n'importe quel layout


Sujet :

Composants Java

  1. #1
    Membre régulier
    Inscrit en
    Décembre 2002
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 152
    Points : 94
    Points
    94
    Par défaut Place des composants dans n'importe quel layout
    Bonjour à tous,

    Je suis en train de sécher sur un problème.

    J'ai écrit une méthode simple qui permet de scanner les contenu d'un JPanel à la recherche de certains composants (JTextField, JComboBox, JCheckBox, etc.).

    Ce que je souhaite est de pouvoir cliquer sur un bouton et que tous ces composants soient automatiquement remplacés par des JLabel. Quand je clique à nouveau sur le bouton, les JLabel laissent de nouveaux la place aux composants d'origine.

    Il faut évidement que tout se fasse dynamiquement, c'est à dire que ma méthode scanne le JPanel à la recherche de ces composants et qu'il relève la "position" des composants dans le layout utilisé (n'importe quel type, GridBagLayout ou autres) pour savoir où pouvoir switcher avec un JLabel.

    Ou existe-t'il une sorte de Renderer pour les JComponent qui retourne le composant à dessiner dans le layout du JPanel et qu'on pourrait faire retourner un JLabel une fois sur deux lorsqu'on clique sur le bouton ?

    Avez-vous une idée sur comment faire çà ?

    Merci d'avance pour votre aide !
    </aliasjcdenton>

    "Un Homme devient vieux lorsque ses regrets prennent la place de ses rêves"

  2. #2
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    En version bourrine mais finalement pas si conne que ça:

    Tu crées un modèle contenant des données, et tu développes deux écrans, un pour l'édition, un pour la saisie qui partagent ce modèle. que tu mets dans un cardLayout. En option tu peux utiliser un layout manager qui permet d'externaliser la config dans un fichier (genre MigLayout), config que tu mets en commun sur les deux panels, en appelant bien sur les divers champs de la même façon pour que la config soit portable...

    Ensuite il ne te restera qu'à switcher au niveau du CardLayout entre les deux écrans.
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  3. #3
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Si tu veux récupérer l'emplacement d'un composant, tu as la méthode getBounds().
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  4. #4
    Membre régulier
    Inscrit en
    Décembre 2002
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 152
    Points : 94
    Points
    94
    Par défaut
    Merci pour vos réponses !

    @sinok : j'avais déjà pensé à ton idée mais çà devient malheureusement vite complexe lorsqu'on veut reproduire à l'identique les 2 panneaux si le panneau source contient des panneaux imbriqués et de layouts différents.

    Le getBounds() fait bien le job (je pensais que le placement dans le JPanel était absolu mais il est relatif) et permet avec l'usage d'une interface de retourner le texte du JLabel de chaque composant en fonction de son type (chaque composant implémentant cette interface).

    Puis on fait qqch du style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Rectangle bounds = LE_COMPOSANT.getBounds();
    Container parentContainer = super.getParent();
    parentContainer.remove(this);
    JLabel label = new JLabel(LE_COMPOSANT.getLabelText()); // getLabelText() est une méthode Override par le componsant qui implémente l'inteface
    parentContainer.add(label);
    label.setBounds(bounds);
    ((JPanel) parentContainer).revalidate();
    parentContainer.repaint();
    J'ai encore des détails à régler avec les panneaux de layout GridBagLayout mais j'y travaille.

    Merci encore pour votre aide !
    </aliasjcdenton>

    "Un Homme devient vieux lorsque ses regrets prennent la place de ses rêves"

  5. #5
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Sinon, toujours avec le MigLayout, une autre possibilité pas trop dégueulasse est de passer par le hidemode combiné à un setVisible sur les composants. Le hidemode permet de spécifier au layout ce qu'il doit faire avec les composants non visibles en ce qui concerne l'espace qu'ils doivent remplir:

    http://migcalendar.com/miglayout/whitepaper.html (chercher hidemode)

    Et d'avoir une méthode qui bascule du mode édition au mode visualisation en settant les composants textuels à non visible (setVisible(false)) et les JLabels à visible (setVisible(true)) et inversement...
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  6. #6
    Membre régulier
    Inscrit en
    Décembre 2002
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 152
    Points : 94
    Points
    94
    Par défaut
    Çà ne joue malheureusement pas dans mon cas car ma méthode de scan prend en paramètre un JPanel principal (contenant les composants, mais pouvant également contenir d'autres JPanel (avec différents layouts), des ScrollPane, des TabbedPane, etc.) et je dois respecter l'agencement fourni par le JPanel principal défini par l'utilisateur et qu'il reste strictement le même.
    </aliasjcdenton>

    "Un Homme devient vieux lorsque ses regrets prennent la place de ses rêves"

  7. #7
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Ta méthode ne tiendra pas la route ...
    Tu peux utiliser getBounds() à un instant t mais au prochain "relayout" (invalidate ou validate) tu perdras tout ce que tu avais fait.

    Le principe des layout c'est d'utiliser les méthodes getMinimumSize(), getMaximumSize() et getPreferredSize() (en tenant également compte des contraintes) pour déterminer les "bounds" (limites : coordonnées + dimensions) des composants du conteneur qu'il "layout" (met en page / agence)
    Le layout est également utilisé pour déterminer les tailles minimales, maximales et préférées du conteneur qu'il agence.

    Le mieux est de créer une sous-classe de JLabel dont les méthodes getMinimumSize(), getMaximumSize() et getPreferredSize() appellent celles du composant remplacé.



    Sachant que ces méthodes se basent parfois sur le conteneur (c'est le cas du SpringLayout je crois), la méthode du CardLayout pour "remplacer" le composant par un JLabel me paraît être une bonne idée.

    En résumé, j'envisagerai la solution suivante :
    • Création d'un modèle qui stocke un ensemble de composants "switchables"
    • Création d'une sous-classe de JPanel qui force l'utilisation d'un CardLayout avec des méthodes pour "switcher" et dont les dimensions sont déterminés par le composant principale (l'indice 0 ?)
    • Remplacer les composants "switchables" par le nouveau conteneur et ajouter les JLabel qui correspondent
    • Instancier le nouveau modele et y ajouter les conteneur de switch
    • Binder le bouton de switch sur l'invocation de la méthode de switch du modèle (celle-ci invoque le switch correspondant sur l'ensemble des conteneurs enregistrés)
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  8. #8
    Membre régulier
    Inscrit en
    Décembre 2002
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 152
    Points : 94
    Points
    94
    Par défaut
    Merci pour ta réponse.

    Je rencontre en effet certains problèmes.

    Je vais étudier ta solution de plus près...
    </aliasjcdenton>

    "Un Homme devient vieux lorsque ses regrets prennent la place de ses rêves"

  9. #9
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Autre option que j'explorerais car moins invasive:
    Tu utilise un layoutmanager à deux couches pour ta frame. Le panel du dessus (pas toujours visible) contient un JPanel opaque contenant lui même les JLabel avec disposés par un layout custom qui va positionner les Jlabels aux mêmes positions que les composants de la partie édition. Comme la partie édition reste "en arrière" sur la frame, le redimensionnement devrait tenir la route.

  10. #10
    Membre régulier
    Inscrit en
    Décembre 2002
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 152
    Points : 94
    Points
    94
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Autre option que j'explorerais car moins invasive:
    Tu utilise un layoutmanager à deux couches pour ta frame. Le panel du dessus (pas toujours visible) contient un JPanel opaque contenant lui même les JLabel avec disposés par un layout custom qui va positionner les Jlabels aux mêmes positions que les composants de la partie édition. Comme la partie édition reste "en arrière" sur la frame, le redimensionnement devrait tenir la route.
    Çà ne jouera malheureusement pas puisque les composants peuvent se trouver dans des JPanel différents (contenu dans le JPanel principal passé en paramètre à ma méthode de scan).
    </aliasjcdenton>

    "Un Homme devient vieux lorsque ses regrets prennent la place de ses rêves"

  11. #11
    Membre régulier
    Inscrit en
    Décembre 2002
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 152
    Points : 94
    Points
    94
    Par défaut
    Bon, je vais tester cette manière :

    Je scanne mon JPanel principal et récursivement tous les JPanel imbriqués (et JTabbedPane et autres Container) à la recherche de mes composants.

    Dès que je trouve un composant, je distingue le layout de son conteneur parent. Je remove() le composant de son conteneur et le remplace par un JPanel contenant le label et le composant. Lors du switch, on rend invisible le composant et visible le label (j'évite justement d'utiliser un CardLayout car je ne veux pas que le JLabel prenne la taille du composant correspondant qui peut être une sous-classe de JTextArea par exemple, donc très grand).

    Il faut juste tenir compte du layout du conteneur pour savoir comment add() le conteneur switchable. S'il s'agit d'un FlowLayout ou d'un BoxLayout c'est facile, si c'est un GridBagLayout, il faut respecter les GridBagConstraint, etc.
    </aliasjcdenton>

    "Un Homme devient vieux lorsque ses regrets prennent la place de ses rêves"

  12. #12
    Membre régulier
    Inscrit en
    Décembre 2002
    Messages
    152
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 152
    Points : 94
    Points
    94
    Par défaut
    Voilà, j'ai testé et çà fonctionne parfaitement de cette manière. Çà me permet d'avoir une structure de conteneurs imbriqués (dans le panneau racine) aussi complexe que je veux.

    Merci beaucoup pour votre aide !
    </aliasjcdenton>

    "Un Homme devient vieux lorsque ses regrets prennent la place de ses rêves"

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Placer correctement des Composants dans un JPanel
    Par Lady dans le forum AWT/Swing
    Réponses: 5
    Dernier message: 14/01/2007, 13h34
  2. (Re) ordre Z des composants dans delphi
    Par laventure dans le forum Langage
    Réponses: 2
    Dernier message: 10/10/2005, 12h30
  3. Pb pour afficher des composants dans la palette
    Par Captain_JS dans le forum C++Builder
    Réponses: 1
    Dernier message: 12/07/2005, 18h35
  4. [VS.NET] [C#] Icone des composants dans l'IDE VS 2003
    Par Ingham dans le forum Windows Forms
    Réponses: 7
    Dernier message: 11/01/2005, 23h50
  5. [Delphi] Icone des composants dans la palette
    Par jacquesberger dans le forum Composants VCL
    Réponses: 2
    Dernier message: 13/04/2004, 15h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo