PDA

View Full Version : Help TreePanel and BeanModelMarker problems



B.Oury
1 Mar 2012, 10:36 AM
Hi,

I have a lot of problems for several days with usage of TreePanel and BeanModel create with BeanModelLookup.get().getFactory(results.getClass()).createModel(myPojo).
In fact in TreeStore (Map<M, TreeModel> modelMap) and TreePanel (Map<M, String> cache) class there are several maps who use object as key.

Therefore, objects are not deleted correctly (for example) because when the method get is applied on the map with my object, and that I see (in debug) that my object is there, it returns null.

My Object:


package be.mims.omnipro.gxt.shared.dto;

import com.extjs.gxt.ui.client.data.BeanModelMarker;
import com.google.gwt.user.client.rpc.IsSerializable;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


public class AgdDemandeDTO implements IsSerializable {
protected Long id;
protected Date dateDebut;
protected PatientDTO patient;

// Default constructor
public AgdDemandeDTO() {
}

/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;

result = prime * result + ((dateDebut == null) ? 0 : dateDebut.hashCode());
result = prime * result + ((patient == null) ? 0 : patient.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());

return result;
}

/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
if (dateDebut == null) {
if (other.dateDebut != null) return false;
} else if (!dateDebut.equals(other.dateDebut)) return false;
if (patient == null) {
if (other.patient != null) return false;
} else if (!patient.equals(other.patient)) return false;
if (id == null) {
if (other.id != null) return false;
} else if (!id.equals(other.id)) return false;

return true;
}

/*
* (non-Javadoc)
*
* @see java.lang.Object#clone()
*/
public AgdDemandeDTO clone() {
AgdDemandeDTO agdDemande = new AgdDemandeDTO();

if (dateDebut != null) {
agdDemande.setDateDebut((Date) dateDebut.clone());
}
if (patient != null) {
agdDemande.setPatient(patient.clone());
}
agdDemande.setId(id);

return agdDemande;
}

/**
* @return the id
*/
public Long getId() {
return id;
}

/**
* @param id the id to set
*/
public void setId(Long id) {
this.id = id;
}

/**
* @return the dateDebut
*/
public Date getDateDebut() {
return dateDebut;
}

/**
* @param dateDebut the dateDebut to set
*/
public void setDateDebut(Date dateDebut) {
this.dateDebut = dateDebut;
}

/**
* @return the patient
*/
public PatientDTO getPatient() {
return patient;
}

/**
* @param patient the patient to set
*/
public void setPatient(PatientDTO patient) {
this.patient = patient;
}

/**
* toString
*/
@Override
public String toString() {
return "AgdDemandeDTO [id =" + id + "]";
}

// Interface generated for using GXT BeanModelFactory.
@BeanModelMarker.BEAN(AgdDemandeDTO.class)
public interface AgdDemandeDTOBeanModel extends BeanModelMarker {
}
}



The use of TreePanel and TreeStore:


private TreeStore treeStore = new TreeStore();
private TreePanel<BeanModel> treePanel = new TreePanel<BeanModel>(treeStore);

//AgdDemandeDTO demande
BeanModelFactory factory = BeanModelLookup.get().getFactory(demande.getClass());
BeanModel objParentDemande= factory.createModel(demande);
treeStore.add(objParentDemande, false);
treeStore.commitChanges();



Later, I delete items and I will add new object and I notice, on delete, it does not happen properly.

Thanks really for your help!!!

Colin Alworth
2 Mar 2012, 7:20 AM
I dont believe that the BeanModel will delegate to your own hashcode and equals methods. It is also worth pointing out that even if it did, if you modified any bean, since the hashcode is different, that model could no longer be found in the HashMap, since its new hash will be different than the one it was stored with.

To gain better control over how elements are stored and tracked, and to be sure that this hash will be immutable, make sure you are using the same BeanModel instance, or something which is clearly equivalent. Consider providing a ModelKeyProvider instance to always maintain a unique key for each item.

And finally, while you have provide the code to see how you set up your example, you haven't demonstrated how you remove items, and the error that occurs. If you can provide such code, it will be easier to see either where the bug is, or where your misunderstanding might be. I'd suggest writing this like a unit test, or a simple entrypoint - adding a few simple items, then attempting to remove one, and demonstrating that it is still present.

B.Oury
6 Mar 2012, 7:13 AM
Hi,

There is a "simple" class to test my problems.



public class SimpleTest implements EntryPoint {

public void onModuleLoad() {
Viewport vp = new Viewport();
AgendaCrmPanelTreeAppointments tree = GWT.create(AgendaCrmPanelTreeAppointments.class);
vp.setLayout(new BorderLayout());
vp.add(tree, new BorderLayoutData(Style.LayoutRegion.CENTER));
RootPanel.get().add(vp);
vp.repaint();
}
}



public class AgendaCrmPanelTreeAppointments extends FormPanel {
private final GreetingServiceAsync agendaService = (GreetingServiceAsync) GWT.create(GreetingService.class);
// private AgendaTreeStore treeStore = new AgendaTreeStore();
private final TreeStore treeStore = new TreeStore();
private final TreePanel<BeanModel> treePanel = new TreePanel<BeanModel>(treeStore);

private final DateTimeFormat fmt = DateTimeFormat.getFormat("dd/MM/yy");
private final String strResponsable = "Responsable";
private final String strChoose = "Choisir comme responsable";
private final ImageResource iconResponsable24 = IconsResources.ICONS.iconResponsableActif24();
private final ImageResource iconChoose24 = IconsResources.ICONS.iconResponsableInactif24();
private Button buttonResponsable;
private final String print = "print";
private final ToolBar toolBar;
private BeanModel oldRdvResponsable;
private AgdDemandeDTO demande;
private AgdRdvDTO selectLastAppointment;
private AgdRdvDTO selectRdv;
private boolean visible;
private List<AgdRdvDTO> rdvs;
private AgdSuiviDTO suivi;

public AgendaCrmPanelTreeAppointments() {

this.setId("AgendaCrmPanelTreeAppointments");
this.setHeading("Aper├žu des demandes");
this.setBorders(false);
this.setScrollMode(Style.Scroll.AUTO);

toolBar = new ToolBar();
buttonResponsable = createButtonResponsable();
toolBar.add(buttonResponsable);
this.setTopComponent(toolBar);

agendaService.getDemandes(new AsyncCallback<List<AgdDemandeDTO>>() {

@Override
public void onFailure(Throwable caught) {
System.out.println("Erreur getDemandes()");
}

@Override
public void onSuccess(List<AgdDemandeDTO> result) {
showDemandes(getModels(result));
}
});

createTreePanel();
add(treePanel);
this.setBorders(true);
this.setLayout(new FitLayout());
this.setSize(500, 500);
this.layout();
}

/**
* Creates the "choose as responsable" button
*
* @return buttonResponsable
*/
private Button createButtonResponsable() {
buttonResponsable = new Button();
buttonResponsable.setScale(ButtonScale.MEDIUM);
buttonResponsable.addSelectionListener(new SelectionListener<ButtonEvent>() {

@Override
public void componentSelected(ButtonEvent buttonEvent) {
selectionResponsableChange();
}
});
buttonResponsable.setEnabled(false);
buttonResponsable.setToolTip(strChoose);
buttonResponsable.setIcon(AbstractImagePrototype.create(iconChoose24));
return buttonResponsable;
}

private void selectionResponsableChange() {
if (treePanel.getSelectionModel().getSelectedItem().getBean() != null) {
if (treePanel.getSelectionModel().getSelectedItem().getBean() instanceof AgdRdvDTO) {
if (((AgdRdvDTO) (treePanel.getSelectionModel().getSelectedItem()).getBean()).getIdRdvCategorie().intValue() == RdvCategorie.RDV.getValue()) {
BeanModel modelRdv = treePanel.getSelectionModel().getSelectedItem();
AgdRdvDTO rdv = modelRdv.getBean();
BeanModel beanSuivi = ((BeanModel) treeStore.getParent(modelRdv));
BeanModel beanDemande = ((BeanModel) treeStore.getParent(beanSuivi));
AgdSuiviDTO suivi = beanSuivi.getBean();
if (suivi.getIdBoss().intValue() != rdv.getId().getIdBoss().intValue()) {
buttonResponsable.setToolTip(strResponsable);
buttonResponsable.setIcon(AbstractImagePrototype.create(iconResponsable24));
buttonResponsable.setEnabled(false);
beanSuivi.set("idBoss", rdv.getId().getIdBoss());
treeStore.update(beanDemande);
treeStore.update(beanSuivi);
treeStore.update(oldRdvResponsable);
treeStore.update(modelRdv);
treeStore.commitChanges();
} else {
buttonResponsable.setToolTip(strChoose);
buttonResponsable.setIcon(AbstractImagePrototype.create(iconChoose24));
buttonResponsable.setEnabled(false);
}
} else {
buttonResponsable.setToolTip(strChoose);
buttonResponsable.setIcon(AbstractImagePrototype.create(iconChoose24));
buttonResponsable.setEnabled(false);
}
}
}
}

/**
* Renders the componenet
*/
void createTreePanel() {
treePanel.setBorders(true);
treePanel.setDisplayProperty(this.print);
treePanel.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);

treePanel.getSelectionModel().addListener(Events.BeforeSelect, new Listener<SelectionEvent<BeanModel>>() {

@Override
public void handleEvent(SelectionEvent<BeanModel> be) {
AgdRdvDTO selectAppointment = null;
AgdDemandeDTO selectDemande = null;
AgdSuiviDTO selectSuivi = null;
BeanModel item = be.getModel();

if (item.getBean() instanceof AgdDemandeDTO) {
BeanModel modelSuivi = (BeanModel) treeStore.getFirstChild(item);
if (modelSuivi != null) {
AgdRdvDTO modelRdv = ((BeanModel) treeStore.getFirstChild(modelSuivi)).getBean();
if (modelRdv.getIdRdvCategorie().intValue() != RdvCategorie.RDV.getValue()) {
return;
}
selectDemande = item.getBean();
selectAppointment = modelRdv;
}
} else if (item.getBean() instanceof AgdSuiviDTO) {
AgdRdvDTO modelRdv = ((BeanModel) treeStore.getFirstChild(item)).getBean();
if (modelRdv.getIdRdvCategorie().intValue() != RdvCategorie.RDV.getValue()) {
return;
}
selectAppointment = modelRdv;
selectSuivi = item.getBean();
} else if (item.getBean() instanceof AgdRdvDTO) {
selectAppointment = item.getBean();
BeanModel beanSuivi = (BeanModel) treeStore.getParent(item);
selectSuivi = beanSuivi.getBean();
BeanModel tmp = (BeanModel) treeStore.getParent(beanSuivi);
if (tmp != null) {
selectDemande = tmp.getBean();
}
}
selectRdv = selectAppointment;
if (selectDemande != null && selectSuivi != null) {
for (AgdRdvDTO rdv : rdvs) {
if (selectLastAppointment != null) {

if (rdv.getId().equals(selectLastAppointment.getId()) && !selectSuivi.equals(suivi)) {
changeRdv(selectDemande, selectSuivi, selectLastAppointment);
}
} else {
if (rdv.getId().equals(selectRdv.getId()) && !rdv.equals(selectRdv)) {
changeRdv(selectDemande, selectSuivi, selectRdv);
}
}
}
}
selectLastAppointment = selectAppointment;
}
});
treePanel.setLabelProvider(new ModelStringProvider<BeanModel>() {

@Override
public String getStringValue(BeanModel model, String property) {
String style = model.get(print);
if (model.getBean() instanceof AgdRdvDTO) {
AgdRdvDTO selectAppointment = model.getBean();
AgdSuiviDTO suiviParent = (AgdSuiviDTO) ((BeanModel) treeStore.getParent(model)).getBean();
UtilisateurDTO user = selectAppointment.getUtilisateur();
if (user != null) {
HumanDTO human = user.getHuman();
if (human != null && human.getId().intValue() == suiviParent.getIdBoss()) {
// style = "<span style='color:red'>" + style + "</span>";
// style = "<b>" + style + "</b>";
style = "<span title='Responsable'><u>" + style + "</u></span>";
// style = "<u>" + style + "</u>";
oldRdvResponsable = model;
}
}
}
return style;
}
});
treePanel.setIconProvider(new ModelIconProvider<BeanModel>() {

@Override
public AbstractImagePrototype getIcon(BeanModel model) {
if (model.getBean() instanceof AgdRdvDTO) {
AbstractImagePrototype icon;
AgdRdvDTO selectAppointment = model.getBean();
if (selectAppointment.getAgdRdvCategorie().getId().intValue() == RdvCategorie.RDV.getValue()) {
icon = AbstractImagePrototype.create(IconsResources.ICONS.iconRdv16());
return icon;
} else if (selectAppointment.getAgdRdvCategorie().getId().intValue() == RdvCategorie.INDISP.getValue()) {
icon = AbstractImagePrototype.create(IconsResources.ICONS.iconIndisponibilite16());
return icon;
} else if (selectAppointment.getAgdRdvCategorie().getId().intValue() == RdvCategorie.REM.getValue()) {
icon = AbstractImagePrototype.create(IconsResources.ICONS.iconRemarque16());
return icon;
}
}
return null;
}
});
treePanel.getSelectionModel().addSelectionChangedListener(new SelectionChangedListener<BeanModel>() {

@Override
public void selectionChanged(SelectionChangedEvent<BeanModel> se) {
if (se.getSelectedItem() != null && se.getSelectedItem().getBean() instanceof AgdRdvDTO) {
AgdRdvDTO rdv = treePanel.getSelectionModel().getSelectedItem().getBean();
AgdSuiviDTO suivi = (AgdSuiviDTO) (((BeanModel) treeStore.getParent(treePanel.getSelectionModel().getSelectedItem())).getBean());
if (suivi.getIdBoss().intValue() != rdv.getId().getIdBoss().intValue()) {
buttonResponsable.setToolTip(strChoose);
buttonResponsable.setIcon(AbstractImagePrototype.create(iconChoose24));
buttonResponsable.setEnabled(true);
} else {
buttonResponsable.setToolTip(strResponsable);
buttonResponsable.setIcon(AbstractImagePrototype.create(iconResponsable24));
buttonResponsable.setEnabled(false);
}
toolBar.layout();
} else {
buttonResponsable.setToolTip("");
buttonResponsable.setIcon(AbstractImagePrototype.create(iconChoose24));
buttonResponsable.setEnabled(false);
}
}
});
}

void showDemandes(List<BeanModel> demandes) {
treeStore.removeAll();

for (BeanModel demande1 : demandes) {
AgdDemandeDTO demande = ((AgdDemandeDTO) demande1.getBean());
addDemande(demande);
}
treeStore.commitChanges();
treePanel.repaint();
treePanel.expandAll();
}

private void addDemande(AgdDemandeDTO demande) {
this.demande = demande.clone();
this.suivi = demande.getListSuivi().get(0).clone();
this.rdvs = new ArrayList<AgdRdvDTO>();
for (AgdRdvDTO agdRdvDTO : demande.getListSuivi().get(0).getListRdv()) {
rdvs.add(agdRdvDTO);
}
BeanModel objParentDemande;
BeanModel objParentSuivi;
BeanModel objParentRdv;

List<AgdSuiviDTO> suivis = demande.getListSuivi();
BeanModel modelDemande = getModel(demande);
setDisplayNameDemande(modelDemande);
objParentDemande = modelDemande;
treeStore.add(objParentDemande, false);
// selectItem(demande);
if (suivis != null) {
for (AgdSuiviDTO suivi : suivis) {
List<AgdRdvDTO> rdvs = suivi.getListRdv();
BeanModel modelSuivi = getModel(suivi);
setDisplayNameSuivi(modelSuivi);
objParentSuivi = modelSuivi;
treeStore.add(objParentDemande, objParentSuivi, false);
// selectItem(suivi);
if (rdvs != null) {
for (AgdRdvDTO rdv : rdvs) {
BeanModel modelRdv = getModel(rdv);
setDisplayNameRdv(modelRdv);
objParentRdv = modelRdv;
treeStore.add(objParentSuivi, objParentRdv, false);
}
}
}
}
treeStore.commitChanges();
}

private void setDisplayNameRdv(BeanModel modelRdv) {
String nom = null;
AgdRdvDTO agdRdvDTO = modelRdv.getBean();
if (agdRdvDTO.getUtilisateur() != null && agdRdvDTO.getUtilisateur().getHuman() != null && agdRdvDTO.getUtilisateur().getHuman().getNomComplet() != null) {
nom = agdRdvDTO.getUtilisateur().getHuman().getNomComplet();
}
modelRdv.set(this.print, nom);
}

private void setDisplayNameSuivi(BeanModel modelSuivi) {
AgdSuiviDTO suivi = modelSuivi.getBean();
String print = fmt.format(suivi.getDateDebut()) + " " + suivi.getHeureSuivi();
modelSuivi.set(this.print, print);
}

private void setDisplayNameDemande(BeanModel modelDemande) {
AgdDemandeDTO demande = modelDemande.getBean();
String nomComplet = null;
if ((demande.getPatient() != null && demande.getPatient().getHuman() != null)) {
nomComplet = demande.getPatient().getHuman().getNomComplet();
}
String print;
if (((nomComplet == null || nomComplet.equals("")) && demande.getIdPatient() == null)) {
print = "Demandeur : " + demande.getDemandeur().getHuman().getNomComplet();
} else {
print = "Client : " + (((nomComplet == null || nomComplet.equals(""))) ? demande.getIdPatient().toString() : nomComplet);
}
modelDemande.set(this.print, print);
}

void updateDemande(AgdDemandeDTO demande) {
if (visible || treePanel.isVisible()) {
for (Object object : treeStore.getModels()) {
BeanModel beanModel = ((BeanModel) object);
if (beanModel.getBean() instanceof AgdDemandeDTO) {
if (((AgdDemandeDTO) beanModel.getBean()).getId().intValue() == demande.getId().intValue()) {
treeStore.removeAll(beanModel);
treeStore.remove(beanModel);
treeStore.commitChanges();
this.layout();
addDemande(demande);

treePanel.repaint();
treePanel.expandAll();
break;
}
}
}
} else {
visible = false;
this.demande = demande;
}
}

List<BeanModel> getModels(List<?> results) {
if (results != null && !results.isEmpty()) {
BeanModelFactory factory = BeanModelLookup.get().getFactory(results.get(0).getClass());
return factory.createModel(results);
} else {
return new ArrayList<BeanModel>();
}
}

BeanModel getModel(Object results) {
if (results != null) {
BeanModelFactory factory = BeanModelLookup.get().getFactory(results.getClass());
return factory.createModel(results);
} else {
return null;
}
}

private void changeRdv(AgdDemandeDTO demande, AgdSuiviDTO suivi, AgdRdvDTO rdv) {
agendaService.changeAppointmentRdv(demande, suivi, rdv, suivi.getAgdQuestionnaire(), true, new AsyncCallback<AgdDemandeDTO>() {

@Override
public void onSuccess(AgdDemandeDTO agdDemandeDTO) {
if (agdDemandeDTO != null) {
updateDemande(agdDemandeDTO);
}
}

@Override
public void onFailure(Throwable caught) {
System.out.println("Error");
}
});
}
}



I work with this tree :
32427

"Graas Nicole" is underlined because she's responsible. Therefore if i click on "Grass Nicole", the button is lighted.

If i click on "Quirinen Vincent", I see that the button is off :

32428
If I click on the button, "Quirinen Vincent" becomes responsible, he's underlined and the button is lighted for him. For "Graas Nicole", the button is off and she isn't underlined.
Because "Quirinen Vincent" becomes responsible, the idResponsible in his parent node is update. You can see that in the method selectionResponsableChange().

The treestore seems to have good data.
But if I click again on "Graas Nicole", normally we must save the changes if there is one (see in the listener Events.BeforeSelect).
But I have already a bug in this section :



else if (item.getBean() instanceof AgdRdvDTO) {
selectAppointment = item.getBean();
BeanModel beanSuivi = (BeanModel) treeStore.getParent(item);
selectSuivi = beanSuivi.getBean();
BeanModel tmp = (BeanModel) treeStore.getParent(beanSuivi);
if (tmp != null) {
selectDemande = tmp.getBean();
}
}

When I modify the parent node (here is beanSuivi), tmp is always null. Because in TreeStore.java, in findWrapper(M item), return modelMap.get(item) returns always null.


In method selectionResponsableChange(), I do that :


treeStore.update(beanDemande);
treeStore.update(beanSuivi);
treeStore.update(oldRdvResponsable);
treeStore.update(modelRdv);

because before I do treeStore.update(beanSuivi); and the beanSuivi's parent always null so I thought that I must update the bean and his parent but that changes nothing.

Thanks...

B.Oury
5 Jun 2012, 4:21 AM
Someone can respond please?

Thanks!