2011-09-07 5 views
2

Je dois créer un panneau de façon dynamique en utilisant des composants personnalisés jsf 2.0. Les contrôles dans le panneau seront lus dynamiquement à partir d'un XML et rendus sur la sélection de l'objet correspondant (Ex: Si Person est sélectionné, je devrais rendre un panneau qui aura des contrôles liés à la personne comme: Champ d'âge de la personne (inputtext), Personne DOB (calendrier) et ainsi de suite). J'essaie de le rendre à partir de la classe de composant qui étend UIComponentBase.Aide sur les composants personnalisés et les Primefaces JSF 2.0

ResponseWriter writer = Util.getResponseWriter(context); 
//start the <table> tag 
writer.startElement(Constants.STR_TABLE, this); 

//start the <tr> tag 
writer.startElement(Constants.STR_TR, this); 

//start the <td> tag 
writer.startElement(Constants.STR_TD, this); 

//encode the button 1 component inside this <td> 
encodeAllComponent(context, getMyPrimePanel()); 

// end the <td> tag 
writer.endElement(Constants.STR_TD); 

//end the <tr> tag 
writer.endElement(Constants.STR_TR); 


//end the <table> tag 
writer.endElement(Constants.STR_TABLE); 

    //private variable to render a panel 
    private Panel myPrimePanel; 

    /** 
    * @return the myPrimePanel 
    */ 
    public Panel getMyPrimePanel() { 
     System.out.println("inside the panel get method------"); 
     if (myPrimePanel.getChildCount() <= 1) { 
       System.out.println("inside the panel creation function"); 
       InputText input = new InputText(); 
       myPrimePanel.getChildren().add(input); 

     } 
     System.out.println("inside the panel get method-------------"); 
     return myPrimePanel; 
    } 

    /** 
    * @param myPrimePanel the myPrimePanel to set 
    */ 
    public void setMyPrimePanel(Panel myPrimePanel) { 
     System.out.println("inside the panel get method-------------"); 
     //initialize the button 1 component 
     this.myPrimePanel = myPrimePanel; 
    } 

Je l'ai fait de cette façon. Mais je reçois une exception de pointeur nul. Comment le panneau avec les contrôles définis peut-il être rendu dynamiquement?

C'est ce que je veux -

==== ==== Commencera rendu dans la méthode get panneau ------ 7 septembre 2011 10:01:42 com.sun.faces.context.PartialViewContextImpl $ PhaseAwareVisitCallback visite SEVERE: java.lang.NullPointerException

+2

Vérifiez la trace de pile de l'exception (dans le journal du serveur). Il doit y avoir un numéro de ligne pour le NPE, tel que "NullPointerException à la ligne xy". Dites-nous quelle ligne il est dans votre code. Cela nous permettrait de vous aider plus facilement. –

+0

Merci pour la réponse. Mais il ne montre aucun numéro de ligne. – JaveDeveloper

Répondre

2

myPrimePanel est null. Vous devrez en assigner une instance pour qu'elle ne soit pas nulle.

Cependant, je pense que vous allez à propos de cette tâche dans le mauvais sens. Vous ne devez pas ajouter de composants à l'arborescence dans la phase de rendu. Vraisemblablement, vous voulez lire, valider et entrer ces données dans le modèle un certain temps. Emettez vos éléments de départ au encodeBegin. Emettez vos éléments d'extrémité au encodeEnd. Ne remplacez pas encodeChildren et assurez-vous que getRendersChildren renvoie la valeur false (valeur par défaut).

Utilisez l'attribut de liaison pour approvisionner le composant dynamique pendant la phase de restauration. Ajoutez un bean géré de portée de requête avec une propriété de type UIComponent et liez-le à l'élément dans votre vue à l'aide de EL. Dans le getter, si la propriété est null, créez une nouvelle instance de votre contrôle personnalisé et ajoutez children.


Considérez ce point de vue:

<h:form> 
    <h:panelGroup id="myPanel" binding="#{componentMakerBean.panel}" /> 
    <h:commandButton value="go" action="#{componentMakerBean.dumpValuesAction}" /> 
</h:form> 

Le panneau est créé et peuplé un haricot:

/** Request scope bean defined in faces-config.xml */ 
public class ComponentMakerBean { 
    private UIPanel panel; 

    public UIPanel getPanel() { 
    if(panel == null) { 
     panel = new HtmlPanelGroup(); 
     for(int i=0; i<3; i++) { 
     panel.getChildren().add(new HtmlInputText()); 
     } 
    } 
    return panel; 
    } 

    public void setPanel(UIPanel panel) { this.panel = panel; } 

    public String dumpValuesAction() { 
    for(Object kid : panel.getChildren()) { 
     if(kid instanceof ValueHolder) { 
     ValueHolder valueHolder = (ValueHolder) kid; 
     System.out.println(valueHolder.getValue()); 
     } 
    } 
    return null; //no navigation 
    } 
} 

Lors de l'exécution, ce émettra trois champs de texte modifiables dont les valeurs seront imprimées dans le journal lorsque le bouton est cliqué.

Ce code a été testé dans un JSP en utilisant Java 5 & JSF 1.1.

+0

Merci pour la réponse. Pouvez-vous me dire plus clairement comment créer? Je suis très nouveau pour les composants personnalisés. Dois-je créer une autre classe qui étend la classe UIComponentTag? Et dans setProperties je devrais faire valueBinding en utilisant le EL est-ce? Pouvez-vous donner un exemple d'extrait pour le même? – JaveDeveloper

+0

@Deepika - vous n'avez pas besoin de balises supplémentaires en utilisant l'approche que j'ai décrite; vous avez juste besoin de faire usage de la fonctionnalité de liaison de composant. Voir la spécification JSF pour plus de détails sur le comportement. J'ai ajouté un exemple de code. – McDowell

+0

Ya c'est vrai. Mais le composant personnalisé n'est pas utilisé ici est-il. Mais mon exigence est d'utiliser un composant personnalisé. :(J'étais capable de rendre les contrôles de la façon que vous avez spécifié mais je devrais faire la même chose en utilisant des composants personnalisés et en jsf 2.0 il ne me permet pas d'inclure un fichier tld car il ne permet que des facelets. – JaveDeveloper

Questions connexes