1

Validating a List<Object> gets a strange error

asked 2018-07-18 20:25:00 +0800

EduardoB gravatar image EduardoB
23 3

Hello,

I am sorry for my English. I am trying to implementate a validator to ensure the user has chosen at least one element in a list selection.

In the ViewModel there is a property:

private List<EvidenciaBean> evidenciasSeleccionadas;

The ZUL has defined a validator:

<vlayout vflex="1" form="@id('fx') @load(vm) @save(vm, before='continuar') @validator('es.aeat.frns.nuix.web.zkuais.creacion.evidencias.SeleccionarEvidenciasOcrCdValidator')">

    <listbox model="@load(vm.listaEvidenciasDisponibles)"
        selectedItems="@bind(fx.evidenciasSeleccionadas)" 
        forward="onOK=botonContinuarOcrEvidenciasCd.onClick"
        multiple="true" checkmark="true" 
        vflex="1">

        <template name="model" var="evidencia">
            <listitem>
                <listcell label="@load(evidencia.nombre)"></listcell>
            </listitem>
        </template>
    </listbox>

The code of the validator is simple, check if list is empty.

public class SeleccionarEvidenciasOcrCdValidator extends AbstractValidator {

@Override
public void validate(ValidationContext ctx) {

    @SuppressWarnings("unchecked")
    AbstractCollection<EvidenciaBean> evidenciasSeleccionadas  = (AbstractCollection<EvidenciaBean>) ctx.getProperties("evidenciasSeleccionadas")[0].getValue();

    //Debe haber seleccionado alguna evidencia
    if ( (evidenciasSeleccionadas == null) || (evidenciasSeleccionadas.isEmpty()) ) {
        String mensajeValidacion = "Debe seleccionar alguna evidencia.";
        addInvalidMessage(ctx, mensajeValidacion);
        Messagebox.show(mensajeValidacion, "Error de validación", Messagebox.OK, Messagebox.ERROR);
        return;
    }

}

}

The problem is that sometimes it works fine, sometimes it works wrong. When it is wrong the error message is: org.zkoss.bind.proxy.ListProxy incompatible with java.util.AbstractCollection

It is very strange because ctx.getProperties('myProperty') has 2 elements. The first element usually contains the correct value as LinkedHasSet object but sometimes the first element contains a ListProxy.

Does anybody know why the order change when property is recovered?

The ZK version I use is 8.0.4

Thanks in advance.

delete flag offensive retag edit

7 Answers

Sort by » oldest newest most voted
1

answered 2018-07-22 04:30:03 +0800

chillworld gravatar image chillworld flag of Belgium
5307 4 9
https://github.com/chillw...

It's actually a very simple explication.
If you set your selected items as null => the listbox implementation will take default a new LinkedHashSet.
Now I was thinking of initializing it would help it, but it won't fix your problem without the proxy.
This fiddle show you the default selection : http://zkfiddle.org/sample/3kvld74/205-Simple-MVVM-sample

Then of course you have the extra step of the proxy between it.
So I'm guessing the proxy would take the instane of the type with what it's created.
You set some selection first => it will be ListProxy (because you use List)
The other time it's initialized with LinkedHashSet => that's the other fault.

The best way is to make your selected items a LinkedHashSet => so every time the proxy is initialized, it will be the correct class.

chill.

link publish delete flag offensive edit
1

answered 2018-07-23 15:50:20 +0800

EduardoB gravatar image EduardoB
23 3

Hello chillworld,

You have made me find the light, thanks!

Blockquote If you set your selected items as null => the listbox implementation will take default a new LinkedHashSet. Blockquote

In the ViewModel class, I used an @Init method where the property was inicializated.

private List<EvidenciaBean> evidenciasSeleccionadas;

public List<EvidenciaBean> getEvidenciasSeleccionadas() {
    return evidenciasSeleccionadas;
}

public void setEvidenciasSeleccionadas(List<EvidenciaBean> evidenciasSeleccionadas) {
    this.evidenciasSeleccionadas = evidenciasSeleccionadas;
}


@Init
public void inicializacion(@ExecutionArgParam("listaEvidencias") List<EvidenciaBean> lista)  {

    listaEvidenciasDisponibles = lista;

    evidenciasSeleccionadas = new ArrayList<>();
}

I have changed the inicialization of evidenciasSeleccionadas to:

@Init
public void inicializacion(@ExecutionArgParam("listaEvidencias") List<EvidenciaBean> lista)  {

    listaEvidenciasDisponibles = lista;

    evidenciasSeleccionadas = null;
}

After this change, validator works fine using:

    AbstractCollection<EvidenciaBean> evidenciasSeleccionadas  = (AbstractCollection<EvidenciaBean>) ctx.getProperties("evidenciasSeleccionadas")[0].getValue();

Regards.

link publish delete flag offensive edit

Comments

Nice to hear your problem is solved

chillworld ( 2018-07-24 00:28:50 +0800 )edit
0

answered 2018-07-20 18:21:36 +0800

hawk gravatar image hawk
2240 1 5
http://hawkphoenix.blogsp... ZK Team

Could you change AbstractCollection<EvidenciaBean> to List? since List should be the matched type.

Since you originally declare below in your ViewModel:

private List<EvidenciaBean> evidenciasSeleccionadas;
link publish delete flag offensive edit
0

answered 2018-07-20 21:38:48 +0800

EduardoB gravatar image EduardoB
23 3

Hello hawk,

I have tried this:

@Override public void validate(ValidationContext ctx) {

List<evidenciabean> evidenciasSeleccionadas = (List<evidenciabean>) ctx.getProperties("evidenciasSeleccionadas")[0].getValue();

Sometimes it works fine, sometimes it does not work, in this case the error is: java.util.LinkedHashSet incompatible with java.util.List

This error is due to the original problem, sometimes the object received in [0] index is a linkedHashSet. In other cases the object received in [0] index is a List.

I am sorry but I have not karma enought to attach some screens to explain it better.

Thanks for your help.

link publish delete flag offensive edit
0

answered 2018-07-25 15:03:50 +0800

EduardoB gravatar image EduardoB
23 3

Hello again,

After solving this problem, I have found the opposite.

In the previous ViewModel the list I would like to validate was empty. The user had to choose at least one element of this list.

Now the user hast to selected at least one element in the list showed. The validator has to check at least one element of this list is selected (by default the list has one element selected).

This new ViewModel is similar, the list I would like to validate is inicializated with one element.

private List<ConfiguracionOcr.IdiomaOcr> idiomasSeleccionados;



@Init
public void inicializacion() {

    this.idiomasSeleccionados = new ArrayList<>();
    this.idiomasSeleccionados.add(ConfiguracionOcr.IdiomaOcr.IDIOMA_ESPANOL);
}

The ZUL has this code:

<vlayout vflex="1" form="@id('fx') @load(vm) @save(vm, before='aceptar') @validator('es.aeat.frns.nuix.web.zkuais.gestion.resultados.PasarOcrDocumentosCdValidator')">

    <listbox model="@load(vm.idiomasDisponibles)"
        selectedItems="@bind(fx.idiomasSeleccionados)" 
        forward="onOK=botonAceptarOcrDocumentosCd.onClick"
        multiple="true" checkmark="true" 
        vflex="1">
        <listhead>
            <listheader label="Idiomas"/>
        </listhead>

        <template name="model" var="idioma">
            <listitem>
                <listcell label="@load(idioma.descripcion)"></listcell>
            </listitem>
        </template>
    </listbox>

    ....

The validator is implemented in the same way:

@Override
public void validate(ValidationContext ctx) {


    @SuppressWarnings("unchecked")
    AbstractCollection<ConfiguracionOcr.IdiomaOcr> idiomasSeleccionados  = (AbstractCollection<ConfiguracionOcr.IdiomaOcr>) ctx.getProperties("idiomasSeleccionados")[0].getValue();

    //Debe haber seleccionado algún idioma
    if ( (idiomasSeleccionados == null) || (idiomasSeleccionados.isEmpty()) ) {
        String mensajeValidacion = "Debe seleccionar algún idioma.";
        addInvalidMessage(ctx, mensajeValidacion);
        Messagebox.show(mensajeValidacion, "Error de validación", Messagebox.OK, Messagebox.ERROR);
        return;
    }

}

}

But sometimes I get the error: org.zkoss.bind.proxy.ListProxy incompatible with java.util.AbstractCollection

So I am confused. Any idea?

link publish delete flag offensive edit
0

answered 2018-07-25 15:26:54 +0800

chillworld gravatar image chillworld flag of Belgium
5307 4 9
https://github.com/chillw...

I think the best is just to use the Collection interface.

You can ask the size, an iterator and ListProxy as AbstractCollection implements this interface.

link publish delete flag offensive edit
0

answered 2018-07-27 19:02:36 +0800

EduardoB gravatar image EduardoB
23 3

Thank you again!

link publish delete flag offensive edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2018-07-18 20:25:00 +0800

Seen: 19 times

Last updated: Jul 27

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More