我对 Groovy 有一点了解:
- 语法更简洁的一些方式
- 闭包在替换 Java 匿名内部类时如何有用。
- 建设者如何使树木建设更容易
有了所有这些,我希望 Groovy SwingBuilder 比在 Java 中进行设置要明显得多。但是我在书本和网络中看到的示例看起来并不比我期望的 Java 版本更简洁或可读。
有人可以举一个很好的例子来说明 Java 与 Groovy,无论是真实的还是人为的,Groovy Swing 的亮点在哪里?
我对 Groovy 有一点了解:
有了所有这些,我希望 Groovy SwingBuilder 比在 Java 中进行设置要明显得多。但是我在书本和网络中看到的示例看起来并不比我期望的 Java 版本更简洁或可读。
有人可以举一个很好的例子来说明 Java 与 Groovy,无论是真实的还是人为的,Groovy Swing 的亮点在哪里?
它没有发光。它只是为您节省了大量代码。您可以抱怨,但正如我所见,这样的表创建比拥有一个独特的模型类、许多不必要的行(例如方法声明和注释等)要好。
table = builder.table(constraints: BorderLayout.CENTER) {
tableModel(list: data) {
propertyColumn(header:'Name', propertyName: 'displayName', editable: false)
closureColumn(header:'Value', read: IDENTITY,
cellRenderer: cellRenderer, cellEditor: cellEditor,
write: {row, newVal->});
} }
除了简单的表创建和非常强大的closureColumn之外,还有一个易于阅读的简单示例:
new SwingBuilder().frame(pack: true, show: true, defaultCloseOperation: JFrame.EXIT_ON_CLOSE) {
panel(layout: new BorderLayout()) {
label constraints: BorderLayout.PAGE_START, "Header"
button constraints: BorderLayout.PAGE_END,
action: action(name: "Footer", closure: { println "Footer pressed" }, accelerator: "Ctrl+K" )
list listData: 1..10, BorderLayout.CENTER
} }
现在,请回答,您将编写多少行代码来实现这样的结果?
编辑:添加了第二个示例 Groovy 非 SwingBuilder 代码。
def panel = new JPanel(new BorderLayout())
panel.add(new JLabel("Header"), BorderLayout.PAGE_START)
panel.add(new JList(*(1..10)), BorderLayout.CENTER)
def button = new JButton(new AbstractAction("Footer") {
{
putValue(ACCELERATOR_KEY, "Ctrl+K");
}
@Override void actionPerformed(ActionEvent actionEvent) {
println "Footer pressed"
}
})
panel.add(button, BorderLayout.PAGE_END)
def frame = new JFrame()
frame.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
frame.contentPane = panel
frame.pack()
frame.visible = true
SwingBuilder 确实提供了比普通 Swing 更简洁易读的 bean 绑定实现。您仍然可以在 SwingBuilder 中使用现有的 Swing 布局或组件。如果您需要某些东西而 SwingBuilder 没有提供,您可以随时为该功能创建一个新的可重用节点。
例如,这就是我在 Griffon 框架中使用 SwingBuilder 与 MigLayout 布局和几个自定义节点的方式:
taskPane(id: "form", title: 'Date Entry', layout: new MigLayout('', '[right][left][left,grow]','')) {
label('Invoice No:')
textField(id: 'invoiceNo', columns: 15, text: bind('invoiceNo', target: model, mutual: true), errorPath: 'invoiceNo')
errorLabel(path: 'invoiceNo', constraints: 'wrap')
label('Date:')
dateTimePicker(id: 'date', localDate: bind('date', target: model, mutual: true), errorPath: 'date', dateVisible: true, timeVisible: false)
errorLabel(path: 'date', constraints: 'wrap')
label('Customer:')
comboBox(id: 'customer', model: model.customer, errorPath: 'customer')
errorLabel(path: 'customer', constraints: 'wrap')
label('Discount:', visible: bind {!model.isDiscAvailable})
numberTextField(id: 'disc', columns: 20, bindTo: 'disc', visible: bind {!model.isDiscAvailable}, errorPath: 'disc')
errorLabel(path: 'disc', visible: bind {!model.isDiscAvailable}, constraints: 'wrap')
}
我相信上面的代码比它的纯 Swing 代码更简洁。