使用groovy expando元类重写JList toString方法以显示groovy类的实例

使用groovy expando元类重写JList toString方法以显示groovy类的实例,groovy,jlist,expandometaclass,Groovy,Jlist,Expandometaclass,在groovy swing应用程序中,我有一个代表教师的类,如下所示: Docente.groovy public class Docente { String codigo String nombre String apellidoPaterno String apellidoMaterno String direccion String tipoDocumento String sexo String telefono

在groovy swing应用程序中,我有一个代表教师的类,如下所示:

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
    }
}
我使用toString方法在JTable中显示教师姓名(带nombre)以及某些其他值。其想法是将其中的一部分显示在表上,其余部分显示在JDialog窗口上,以便执行son CRUD操作

假设sw是groovy的SwingBuilder对象的实例,grdDocentes是JTable的id,我使用以下代码填充该表:

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()是用于从数据库中获取所有教师的方法。第二列(它)显示Docente实例本身,正如预期的那样,它显示调用toString()方法的nombre属性。我这样做是因为每当我需要获取对象的其他属性时,我发现获取表的第二列很方便

现在,在另一个用户界面上,我想在JList中显示这些教师,但格式不同。这就是元类的作用。在另一个接口中,我想重写Docente类上的toString()。因此,为此,我使用以下方法:

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
        }

...
这里,lstDocentesDisponibles是JList的id。当代码到达println it.toString()行时,它使用重写的toString()并在默认输出流中显示“no entiendo”。但是,当我查看JList时,会显示原始的toString()。我错过了什么

如有任何提示,我们将不胜感激

谢谢


爱德华多。

我打赌:JList不会通过元类。装饰你的模型怎么样

class DocenteForJList { 
  Docente docente
  String toString() { docente.with { "$nombre ($codigo)" } }
}

def docentes = DocenteDespachador.obtenerDocentes()
docentes.each {
  model.addElement new DocenteForJList(docente:it)
}

皮蒂。我想知道这是否会被认为是Groovy中的一个bug。我接受这个建议。非常感谢@Will P。顺便说一句,我使用了groovy 1.8.4。@ecavero,我认为这是正确的行为。groovy中的每个方法调用都要经过元类。java中的groovy代码:
obj.method()
看起来像:
obj.getMetaClass().invokeMethod(“方法”)内部JList将仅通过java代码。要从java中看到,当您重新定义
toString()
方法时,需要重新编译代码。因此,我猜您的意思是SwingBuilder创建了一个java JList对象,而不是一个扩展GroovyObject的JList。我说得对吗?对不起,耽搁了这么长时间。但是是的,SwingBuilder是javax.swing(一个JavaAPI)的包装器,所以它不能通过Groovy的元类。无论如何,我认为使用不同的类是一种很好的方法:它分离了模型的表示方式,让我想起了JSF2中的支持bean是如何工作的:面向它工作的屏幕。要强制JList遍历元类,我想您可以扩展JList并创建自己的GroovyJList(并以某种方式将其附加到SwingBuilder),我认为这将按照您想要的方式工作:动态重写toString()方法。