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

JSF Java Discussion :

Custom component à partir de deux composants


Sujet :

JSF Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Mai 2008
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 39
    Par défaut Custom component à partir de deux composants
    Bonjour,

    J'ai une question à vous poser concernant la création d'un custom component JSF.
    Est ce qu'il est possible de créer un composant à partir de de deux composant Aet B.
    On a deux modes d'affichage d'une page html ,un mode edition et un mode prévisualisation,pour le mode 1 le custom composant doit retouner le composant A et pour l'autre mode il renvoie le composant B.


    beaucoup d'avance.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Y a plusieurs possibilité d'avoir ce genre de comportement:

    La première c'est de créer un custom component qui se crée automatiquement 2 childs, et dont le "rendered" pointe sur la condition de read/write ainsi tu a à l'arrivée trois composants:

    le tiens, une child qui est le readonly et un child qui est le write


    Une autre possibilité (est qu'un utilise avec succès ici) apparait si t'as beaucoup d'état différent à gérer ou si tes deux type d'affichage (A et B) utilisent un même set de données au départ. Ca consiste à créer un seul composant, mais à avoir plusieurs renderer. Y a un renderer "maitre" qui est associé au composant, et une série de classes implémentant aussi l'interface renderer, et que le renderer maitre appelle en fonction de certaines conditions liée au composant. Dans notre cas, c'est un paramètre du composant qui donne l'info sur le renderer à choisir parmis une liste d'une dizaine. C'est en fait une simple application du delegate pattern où le délégué est choisi au vol

    Note que, a part le renderer maitre, les autre renderer ne sont pas inscrit dans la liste des renderers du faces-config. On ne fait qu'utiliser l'interface, ils ne sont pas associés à des composants

  3. #3
    Rédacteur
    Avatar de romaintaz
    Homme Profil pro
    Java craftsman
    Inscrit en
    Juillet 2005
    Messages
    3 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Java craftsman
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2005
    Messages : 3 790
    Par défaut
    Sinon on peut faire des compositions à partir du moment où on utilise Facelets...
    Nous sommes tous semblables, alors acceptons nos différences !
    --------------------------------------------------------------
    Liens : Blog | Page DVP | Twitter
    Articles : Hudson | Sonar | Outils de builds Java Maven 3 | Play! 1 | TeamCity| CitConf 2009
    Critiques : Apache Maven

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    et faire des custom component sur facelets c'est accessiorement plus facile (même sans passer par les compositions) car tu peut te passer du boulot chiant de définir une taglib jps :p

  5. #5
    Membre averti
    Inscrit en
    Mai 2008
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 39
    Par défaut
    Citation Envoyé par romaintaz Voir le message
    Sinon on peut faire des compositions à partir du moment où on utilise Facelets...
    Citation Envoyé par tchize_ Voir le message
    et faire des custom component sur facelets c'est accessiorement plus facile (même sans passer par les compositions) car tu peut te passer du boulot chiant de définir une taglib jps :p
    J'ai déja utilisé les Facelete pour un autre composant(des labels editables et ça marche trés bien),mais dans le cadre de meme projet ,je suis demandé de mettre mes boutons comme editables aussi ,le problème est que pour le bouton c'est un peu difficile de limiter les nombres des attributs qu'on doit associer au composant(au contraire d'un Label qu'on un seul attribut)
    c'est pourcela J'ai choisi de voir avec l'autre solution ,et définir une Taglib

  6. #6
    Membre averti
    Inscrit en
    Mai 2008
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 39
    Par défaut
    Bonjour ,
    je suis arrivé à créer le composant qui se compose de deux composants le :htmlCommandButton et le inplaceInput. Tchize_
    voila le code qu j'ai utilisé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    public class UI18nCommandBtn extends HtmlPanelGroup {
        private HtmlCommandButton commandBtn;
        private HtmlInplaceInput inplaceInput;
        public static final String COMPONENT_FAMILY = "MyCmd";
        public static final String COMPONENT_TYPE = "ui18nCod";
        public static final String INPUT_1_VALUE_ATTR_NAME = "input1Value";
     
     
        @Override
        public String getFamily() {
            return COMPONENT_FAMILY;
        }
     
        public UI18nCommandBtn() {
            Application f_app = getFacesContext().getApplication();
            commandBtn = (HtmlCommandButton) f_app.createComponent(HtmlCommandButton.COMPONENT_TYPE);
            getChildren().add(commandBtn);
            inplaceInput = (HtmlInplaceInput) f_app.createComponent(HtmlInplaceInput.COMPONENT_TYPE);
            getChildren().add(inplaceInput);
        }
     
        @Override
        public void setId(String id) {
            commandBtn.setId(id + "Cmd");
            inplaceInput.setId(id + "Input");
            super.setId(id);
        }
     
        public void setInput1Value(String input1_value) {
            commandBtn.setValue(input1_value);
            inplaceInput.setValue(input1_value);
        }
     
        @Override
        public void setValueBinding(String attr_name, ValueBinding vb) {
            if (attr_name.equals(INPUT_1_VALUE_ATTR_NAME)) {
                commandBtn.setValueBinding("value", vb);
                return;
            }
            if (attr_name.equals(INPUT_1_VALUE_ATTR_NAME)) {
                inplaceInput.setValueBinding("value", vb);
                return;
            }
            super.setValueBinding(attr_name, vb);
        }
     
        public Object processSaveState(FacesContext context) {
            Object superState = super.processSaveState(context);
            return new Object[]{superState, new Integer(getChildCount())};
        }
     
        public void processRestoreState(FacesContext context, Object state) {
             Object[] values = (Object[]) state;
            Integer savedChildCount = (Integer) values[1];
            for (int i = getChildCount() - savedChildCount.intValue(); i > 0; i--) {
                getChildren().remove(0);
            }
            super.processRestoreState(context, values[0]);
        }
     
    }
    J'ai déclaré mes childs dans le constructeur ,mais à chaque restore state je vide les liste des childs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    public class I18nCommandBtnTag extends UIComponentTag {
        private String _input1_value = null;
     
        @SuppressWarnings("unchecked")
        protected void putAttribute(UIComponent comp, String attr_name, String value) {
            if (attr_name == null) return;
            if (isValueReference(value)) {
                comp.setValueBinding(attr_name, getFacesContext().getApplication().createValueBinding(value));
                return;
            }
            comp.getAttributes().put(attr_name, value);
        }
     
        @Override
        protected void setProperties(UIComponent comp) {
            super.setProperties(comp);
            putAttribute(comp, UI18nCommandBtn.INPUT_1_VALUE_ATTR_NAME, _input1_value);
            putAttribute(comp, UI18nCommandBtn.INPUT_1_VALUE_ATTR_NAME, _input1_value);
        }
     
        public String getComponentType() {
            return UI18nCommandBtn.COMPONENT_TYPE;  //To change body of implemented methods use File | Settings | File Templates.
        }
     
        @Override
        public String getRendererType() {
            return "javax.faces.Group";
        }
     
        public void setInput1Value(String input1_value) {
            _input1_value = input1_value;
        }
     
        @Override
        public void release() {
            super.release();
            _input1_value = null;
     
        }
    }
    et dans le faces-config
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     <component>
            <component-type>ui18nCod</component-type>
            <component-class>com.sqli.kmji18njsf.web.ui.component.UI18nCommandBtn</component-class>
        </component>
       <render-kit>
     		<renderer>
    			<component-family>MyCmd</component-family>
    			<renderer-type>javax.faces.Group</renderer-type>
    			<renderer-class>com.sun.faces.renderkit.html_basic.GroupRenderer</renderer-class>
    		</renderer>
    	</render-kit>
    Il y a encore quelques soucis mais ce que je voudrais bien savoir si la gestion des attributs dans l'appel de mon l'utilisation de mon tag.
    Est ce que je doit déclarer tous les attributs (celles de HtmlCommandButton et le HtmlInplaceInput,plus que 50 attributs )pour qu' elles fonctionnent correctement dans mon composant ou il y 'a moyen de gérer ça automatiquement;surtout que les composants que j'utilise sont des composants standards .

    Merci d'avance

  7. #7
    Membre averti
    Inscrit en
    Mai 2008
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 39
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Y a plusieurs possibilité d'avoir ce genre de comportement:

    Une autre possibilité (est qu'un utilise avec succès ici) apparait si t'as beaucoup d'état différent à gérer ou si tes deux type d'affichage (A et B) utilisent un même set de données au départ. Ca consiste à créer un seul composant, mais à avoir plusieurs renderer. Y a un renderer "maitre" qui est associé au composant, et une série de classes implémentant aussi l'interface renderer, et que le renderer maitre appelle en fonction de certaines conditions liée au composant. Dans notre cas, c'est un paramètre du composant qui donne l'info sur le renderer à choisir parmis une liste d'une dizaine. C'est en fait une simple application du delegate pattern où le délégué est choisi au vol
    Merci Beaucoup pour la réponse tchize.
    Je serai preneur si tu me donne plus de détails sur la deuxiéme méthode,surtout que c'est mon premier composant jsf (et il est composite)Je voudrai en fait utiliser deux composants standards un HtmlcommandButton et un HtmlInplaceInput(richafaces) alors je vais essayer d'utiliser leurs renderers de bases dans le renderer maitre ,je vois pas comment je vais les appeler dans mon renderer maitre?

    Merci

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Citation Envoyé par helios2092 Voir le message
    Merci Beaucoup pour la réponse tchize.
    Je serai preneur si tu me donne plus de détails sur la deuxiéme méthode,surtout que c'est mon premier composant jsf (et il est composite)Je voudrai en fait utiliser deux composants standards un HtmlcommandButton et un HtmlInplaceInput(richafaces) alors je vais essayer d'utiliser leurs renderers de bases dans le renderer maitre ,je vois pas comment je vais les appeler dans mon renderer maitre?

    Merci
    Ca passera pas. Ca ne peut marcher que si tes différents renderers sont au courant qu'il partage un type de composant de base commun. Tu ne passe par par divers composant, tu ne fait que splitter ton renderer en plusieurs implémentation et en choisir une au vol. La pluspart des renderer font du typecasting dans leur code vers le composant qu'il sont supposé mettre en rendu, hors quand HtmlcommandButtonRenderer va tenter le typcasting, t'aura un classcast exception


    Dans ton cas, si tu veux que ton composant switche entre deux composants standard, il faut passer par un pur composite, donc tu devra avoir un arbre à 3 composant (première solution).

    Créer les childs est pas super dur, mais, si tu ne passe pas par les composants composites de facelets qui te permettent de le faire direct en xhtml, il faut faire gaffe à ton code java

    1) ne pas créer les childs dans le constructeur, car une fois ceux-ci dans l'arbre jsf, il y resteront pour une durée plus longue que celle de ta classe java -> au prochain new il sera irrelevant de créer les childs. A la place, surcharger les différentes méthodes du Component, et checker si des childs sont présent. Si pas, les créer au vol (une sorte de création "lazy").

    2) on ne crée pas un composant avec un new xxxxx(); en JSF. On passe par FacesContext.getApplication().createcomponent()

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

Discussions similaires

  1. Custom Event entre deux composants
    Par Will66 dans le forum MXML
    Réponses: 1
    Dernier message: 03/01/2008, 13h20
  2. Dessiner une image à partir d'un composant
    Par lilou77 dans le forum Interfaces Graphiques en Java
    Réponses: 19
    Dernier message: 16/11/2005, 11h47
  3. [C#] custom control à partir d'une image / alpha blending
    Par Cyberwan dans le forum Windows Forms
    Réponses: 5
    Dernier message: 13/11/2005, 21h59
  4. [Component] Récupérer un Component à partir du Name
    Par molusk dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 12/07/2005, 18h27
  5. [JSF] mon premier custom component
    Par anitshka dans le forum JSF
    Réponses: 5
    Dernier message: 14/06/2005, 13h31

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