Question

i have an issue with a DropDownChoice (the DDC) component. The situation is as following: I want to create a simple registry page for a contest. So i need a team with participants. I have created a form (which is a composition of different panels/forms) on which you can enter the name, age and 'position in the game'. Then you press the 'add participant' button and the participant should appear in the DropDownChoice.

I am new to Apache Wicket and actually i am glad i get the form to show on the screen and to see that the participants are actually added to the DDC. But here comes the issue: All of the participants in the DDC are 'turned into' the last one added. In other words: suppose i create the participant Jeff. Jeff gets added to the DDC, no problem. Then i create Mike. When i add Mike to the DDC and look at the available participants, Jeff seems to have been turned into Mike. So at this point, i do have 2 participants in my team, but the first one,Jeff, i suddenly Mike as well. And it is not only the property which is displayed that has changed. It is the complete content of the Participant object that turns into Mike.

Now if i would like to add Janine, Jeff and Mike would both turn into Janine and i would have 3 'Janine participants' in my DDC. I ll add the code of the 'TeamForm', which i believe is the most relevant. If needed, i can put more code on.

    package com.tvh.tournamentregistry.form;

import com.tvh.tournamentregistry.model.Participant;
import com.tvh.tournamentregistry.model.Team;
import com.tvh.tournamentregistry.panel.ParticipantPanel;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.ChoiceRenderer;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.Model;

public class TeamForm extends Form {

    public TeamForm(String id){
        super(id);

        final Team team = new Team();
        CompoundPropertyModel<Team> teamModel = new CompoundPropertyModel<Team>(team);
        setModel(teamModel);

        add(new TextField("name"));

        Model<Participant> participantModel = new Model<Participant>();
        ChoiceRenderer<Participant> teamViewRenderer = new ChoiceRenderer<Participant>("firstname");
        final DropDownChoice<Participant> teamView = new DropDownChoice<Participant>("players",participantModel, team.getPlayers(), teamViewRenderer){

            @Override
            protected boolean wantOnSelectionChangedNotifications() {
                return true; 
            }            
        };
        add(teamView);

        final ParticipantPanel participantPanel = new ParticipantPanel("participantpanel");
        add(participantPanel);

        Button addParticipant = new Button("addparticipant"){
            @Override
            public void onSubmit() {
                Participant participant = (Participant) participantPanel.getModel().getObject();
                team.getPlayers().add(participant);
                teamView.setChoices(team.getPlayers());
                teamView.render();
                participantPanel.clear();
            }
        };

        addParticipant.setDefaultFormProcessing(false);
        add(addParticipant);

    }

    @Override
    protected void onSubmit() {
        super.onSubmit(); //To change body of generated methods, choose Tools | Templates.
    }   
}

I have debugged the little application and what i saw was quite disturbing. i put a breakpoint on

Participant participant = (Participant) participantPanel.getModel().getObject();

after adding 2 participants, so i could have a look at the

 team.getPlayers() 

method which returns a list of participants. The model that gets returned by the paricipantspanel (which is a custom method, passing the model from the form in that panel) is correct. It returns the participant that i have entered in my form. But when i look in the team list, even before my debugger get to that line, i can see that all the other participants have 'changed' already. And i am not touching the list, only adding new participants.

Any thoughs anybody? Thanks! If this was absolutely not clear, please ask!

Was it helpful?

Solution

Each time you add a new participant, the ParticipantPanel must have its model "re-initialized" otherwise its model object references the same object all the time.

In detail:

Participant a.

On first render, your panel uses this participant so on add, it adds it to you list.

After that, while re-rendering, the model object of the panel is still point to participant a. So changes affect the old object. That's why your dropdown has your single participant repeated.

OTHER TIPS

Try the following:

Instead of using getter, use PropertyModel

new DropDownChoice<Participant>("players",participantModel, team.getPlayers(), teamViewRenderer)

change to

new DropDownChoice<Participant>("players",participantModel, new PropertyModel(team, "players"), teamViewRenderer)

Specify idExpression in ChoiceRenderer

new ChoiceRenderer<Participant>("firstname");

change to

new ChoiceRenderer<Participant>("firstname", "id");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top