groovyjlistexpandometaclass

Override JList toString method with groovy expando metaclass to display instances of groovy classes


In a groovy swing application, I have a class that represents teachers like the following:

Docente.groovy

public class Docente {
    String codigo
    String nombre
    String apellidoPaterno
    String apellidoMaterno
    String direccion
    String tipoDocumento    
    String sexo
    String telefono
    String correo

    String toString() {
        nombre
    }
}

I use the toString method to display the teachers name (with nombre) in a JTable, along with certain other values. The idea es to show some of them on the table and the rest of them on a JDialog window in order to preform son CRUD operations.

Assuming that sw is an instance of groovy's SwingBuilder object, and grdDocentes is the id of the JTable, I use the following code to populate that table:

DocentesUI.groovy

...
def tm = sw.grdDocentes.model
tm.rowCount = 0
def doc = DocenteDespachador.obtenerDocentes()
doc.each {
    tm.addRow([it.codigo, it, it.apellidoPaterno, it.apellidoMaterno] as Object[])
}   

... 

ObtenerDocentes() is the method uses to get all the teachers from the databse. The second column (it) es the Docente instance itself and, as expected, it displays the nombre property calling the toString() method. I do this, because I find it convinient to get the second column of this table whenever I with to get the other properties of the object.

Now, on another user interface, I'd like to display these teachers in a JList, but in a diferent format. Here is where the metaClass comes in. In this other interface, I'd like to override the toString() on my Docente class. So, for that, I use the following:

AsignarDocenteUI.groovy

...
        def model = sw.lstDocentesDisponibles.model
        Docente.metaClass.toString = {
            return "No entiendo"
        }           
        def docentes = DocenteDespachador.obtenerDocentes()
        docentes.each {
            println it.toString()
            println it
            model.addElement it
        }

...

Here, lstDocentesDisponibles is the id of the JList. When the code reaches the println it.toString() line, it uses the overriden toString() and displays "no entiendo" to the default outputstream. However, when I look at the JList, the original toString() gets displayed. What am I missing here?

Any hints is appreciated.

Thanks,

Eduardo.


Solution

  • My bet: JList won't go through metaClass. What about decorating your model?

    class DocenteForJList { 
      Docente docente
      String toString() { docente.with { "$nombre ($codigo)" } }
    }
    
    def docentes = DocenteDespachador.obtenerDocentes()
    docentes.each {
      model.addElement new DocenteForJList(docente:it)
    }