有没有办法使用 groovy swing builder 绑定语法将数据绑定到列表和/或表?我只能找到将字符串和数字等简单属性绑定到文本字段、标签或按钮文本的简单示例。
3 回答
环顾四周,我能看到的最好的结果是使用 GlazedLists 而不是标准的 Swing 列表
http://www.jroller.com/aalmiray/entry/glazedlists_groovy_not_your_regular
有一个GlazedList 插件。这篇文章很有帮助。Griffon 家伙对 GlazedLists 发誓。
我只是做了这样的事情——手动做真的不难。它仍在进行中,但如果它可以帮助任何人,我可以提供我所拥有的。到目前为止,它在两个方向上绑定数据(更新数据更新组件,编辑表更新数据并向“行”的任何 propertyChangeListeners 发送通知)
我使用一个类来定义表格的一行。你创建这个类来定义你的表的性质。它看起来像这样:
class Row
{
// allows the table to listen for changes and user code to see when the table is edited
@Bindable
// The name at the top of the column
@PropName("Col 1")
String c1
@Bindable
// In the annotation I set the default editable to "false", here I'll make c2 editable.
// This annotation can (and should) be expanded to define more column properties.
@PropName(value="Col 2", editable=true)
String c2
}
请注意,一旦将其余代码打包到一个类中,这个“Row”类就是唯一需要创建以创建新表的东西。您为每一行创建此类的实例,将它们添加到表格中,然后您就完成了——除了将表格放入框架之外,没有其他 gui 工作。
这个类可能包含更多的代码——我打算让它包含一个轮询数据库并更新绑定属性的线程,然后表应该立即获取更改。
为了提供自定义列属性,我定义了一个如下所示的注释(我计划添加更多):
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface PropName {
String value();
boolean editable() default false
}
其余的是构建表的类。我将它保存在一个单独的类中,以便可以重用(通过用不同的“Row”类实例化它)
注意:我在粘贴它时将其删除,因此如果没有一点工作它可能无法运行(可能是大括号)。它曾经包含一个框架,我将其删除以仅包含表格。您需要将从 getTable() 返回的表格包装在一个框架中。
public class AutoTable<T>
{
SwingBuilder builder // This way external code can access the table
def values=[] // holds the "Row" objects
PropertyChangeListener listener={repaint()} as PropertyChangeListener
def AutoTable(Class<T> clazz)
{
builder = new SwingBuilder()
builder.build{
table(id:'table') {
tableModel(id:'tableModel') {
clazz.declaredFields.findAll{
it.declaredAnnotations*.annotationType().contains(PropName.class)}.each {
def annotation=it.declaredAnnotations.find{it.annotationType()==PropName.class
}
String n=annotation.value()
propertyColumn(header:n, propertyName:it.name, editable:annotation.editable())
}
}
tableModel.rowsModel.value=values
}
}
// Use this to get the table so it can be inserted into a container
def getTable() {
return builder.table
}
def add(T o) {
values.add(o)
o.addPropertyChangeListener(listener)
}
def remove(T o) {
o.removePropertyChangeListener(listener)
values.remove(o)
}
def repaint() {
builder.doLater{
builder.table.repaint();
}
}
}
可能有一种方法可以在没有添加/删除的情况下通过公开可绑定列表来做到这一点,但它似乎需要更多的工作而没有很多好处。
在某个时候,我可能会将完成的课程放在某个地方——如果你已经读到这里并且仍然感兴趣,请在评论中回复,我一定会尽快完成。