1、通过一个例子来学习建造器
-
创建一个xml文件
-
/** * * @author liangchen* @date 2020/11/20 */ // 11.3 def builder = new groovy.xml.MarkupBuilder() builder.numbers { //文本 description 'Square and factors of 10..15' for (i in 10..15) { // 括号中是属性 number(value: i, square: i * i) { for (j in 2..<i) { if (i % j == 0) { factor (value:j) } } } } } /** * 结果 * <numbers> * <description>Square and factors of 10..15</description> * <number value='10' square='100'> * <factor value='2' /> * <factor value='5' /> * </number> * <number value='11' square='121' /> * <number value='12' square='144'> * <factor value='2' /> * <factor value='3' /> * <factor value='4' /> * <factor value='6' /> * </number> * <number value='13' square='169' /> * <number value='14' square='196'> * <factor value='2' /> * <factor value='7' /> * </number> * <number value='15' square='225'> * <factor value='3' /> * <factor value='5' /> * </number> * </numbers> * */
-
2、使用NodeBuilder建造一个对象树
2.1、仔细看一下建造器的代码
-
构建发票–》条目–》产品一个Node
-
/** * @author liangchen* @date 2020/11/20 */ def builder = new NodeBuilder() def ulcDate = Date.parse("yyyy-MM-dd", '2015-01-01') def otherDate = Date.parse('yyyy-MM-dd', '2015-02-02') // 构建一个nodeBuilder 节点, 然后使用grep查询node节点的数据 def invoices = builder.invoices { invoice(date: ulcDate) { item(count: 5) { product(name: 'ULC', dollar: 1499) } item(count: 1) { product(name: 'Visual Editor', dollar: 499) } } invoice(date: otherDate) { item(count: 4) { product(name: 'Visual Editor', dollar: 499) } } } // @符号在grep是引用 soldAt = invoices.grep{ it.item.product.any{it.'@name' == 'ULC'} }.'@date' assert soldAt == [ulcDate]
-
2.2、理解建造概念
- 方法名就是节点名称(第一个方法根节点)
- 方法的参数就是节点属性 (key:value)形式
2.3、建造中增加一些智能的逻辑(一般为控制语句)
-
package com.jack.groovy.ch11 /** * @author liangchen* @date 2020/11/20 */ TimeZone.default = TimeZone.getTimeZone("CET") def builder = new NodeBuilder() def invoices = builder.invoices { for (day in 1..3) { def invDate = Date.parse('yyyy-MM-dd', '2015-01-0$day') invoice(date: invDate) { item(count: day) { product(name: 'ULC', dollar: 1499) } } } } def writer = new StringWriter() invoices.print(new PrintWriter(writer)) println writer.toString() // 深度遍历节点 println invoices.depthFirst()*.name() // 广度遍历节点 println invoices.breadthFirst()*.name()
3、MarkupBuilder使用
3.1、建造xml
-
例子
-
package com.jack.groovy.ch11 import groovy.xml.MarkupBuilder /** * @author liangchen* @date 2020/11/20 */ // 11.6 TimeZone.default = TimeZone.getTimeZone("CET") def writer = new StringWriter() def builder = new MarkupBuilder(writer) builder.invoices { for (day in 1..3) { def invDate = Date.parse('yyyy-MM-dd', '2015-01-0$day') invoice(date: invDate) { item(count: day) { product(name: 'ULC', dollar: 1499) } } } } println writer.toString() // 用单引号也是可以了 def web = builder.'web-app' { builder.'display-name'('Groovy WebApp') } println writer.toString()
-
3.2、建造HTML
-
生成HTML
-
package com.jack.groovy.ch11 import groovy.xml.MarkupBuilder /** * @author liangchen* @date 2020/11/20 */ // 11.7. HTML GUI markupBuilder def writer = new FileWriter('markup.html') def html = new MarkupBuilder(writer) html.html{ head{ title 'Constructed by MarkupBuilder' } body{ h1 'What can I do with MarkupBuilder?' form(action: 'whatever'){ for (line in ['Produce HTML', 'Produce XML', 'Have some fun']) { input(type: 'checkbox', checked: 'checked', id: line, '') label(for: line, line) br() } } } } /** * <html> * <head> * <title>Constructed by MarkupBuilder</title> * </head> * <body> * <h1>What can I do with MarkupBuilder?</h1> * <form action='whatever'> * <input type='checkbox' checked='checked' id='Produce HTML'></input> * <label for='Produce HTML'>Produce HTML</label> * <br /> * <input type='checkbox' checked='checked' id='Produce XML'></input> * <label for='Produce XML'>Produce XML</label> * <br /> * <input type='checkbox' checked='checked' id='Have some fun'></input> * <label for='Have some fun'>Have some fun</label> * <br /> * </form> * </body> * </html> */
-
4、StreamingMarkupBuilder
-
import groovy.xml.StreamingMarkupBuilder /** * @author liangchen* @date 2020/11/20 */ // 去掉空格子类,尽可能最小,缩成一行 def builder = new StreamingMarkupBuilder() // 绑定数据 def writable = builder.bind{ invoices { for (day in 1..3) { def invDate = Date.parse('yyyy-MM-dd', '2015-01-0$day') invoice(date: invDate) { item(count: day) { product(name: 'ULC', dollar: 1499) } } } } } def result = writable.toString() println result
5、AntBuilder 任务自动
5.1、从Ant脚本到Groovy脚本
5.2、AntBuilder 如何工作
5.3、自动脚本的逻辑
package com.jack.groovy.ch11
import groovy.ant.AntBuilder
/**
* @author liangchen* @date 2020/11/20
*/
ant = new AntBuilder()
if (!System.properties.'java.version'.contains('1.7')) {
ant.fail 'This build script requires JDK 1.7.x but was '
+ System.properties.'java.version'
}
6、SwingBuilder轻松构建GUI
6.1、读取密码
6.2、创建Swing组件
6.3、排列组件
6.4、引用组件
6.5、使用Swing的功能
-
package com.jack.groovy.ch11 import groovy.swing.SwingBuilder import java.awt.BorderLayout /** * @author liangchen* @date 2020/11/20 */ swing = new SwingBuilder() frame = swing.frame(title: 'Password'){ passwordField(columns:10, actionPerformed:{ event -> println event.source.text System.exit(0) }) } frame.pack() frame.visible = true // 11.6.2 swing = new SwingBuilder() frame = swing.frame(title: 'Demo'){ menuBar { menu('File'){ menuItem 'New' menuItem 'Open' } } panel { label 'Label1' slider() comboBox(items:['one','two','three']) } } frame.pack() frame.visible = true // 11.6.3 swing = new SwingBuilder() frame = swing.frame(title:'Layout Demo') { panel(layout: new BorderLayout()) { button(constraints: BorderLayout.NORTH, 'North') button(constraints: BorderLayout.CENTER, 'Center') button(constraints: BorderLayout.SOUTH, 'South') button(constraints: BorderLayout.EAST, 'East') button(constraints: BorderLayout.WEST, 'West') panel { textField(columns: 10, id:'message') button(text: 'Print', actionPerformed: { event -> println event.source.parent.components[0].text println swing.message.text println message.text }) } } } frame.pack() frame.visible = true
6.6、使用模式
-
使用mvc
-
package com.jack.groovy.ch11 import groovy.swing.SwingBuilder import groovy.transform.Canonical import javax.swing.JLabel import javax.swing.JTable import javax.swing.table.TableCellRenderer import java.awt.* /** MVC * @author liangchen* @date 2020/11/20 */ // data 定义数据 model @Canonical class NamedColor{ String name Color foreground, background } purple = new NamedColor('Purple', Color.WHITE, new Color(127,0,255)) mediumBlue = new NamedColor('Blue', Color.WHITE, new Color(64, 128, 255)) brightYellow = new NamedColor('Yellow', Color.BLACK, Color.YELLOW) brightRed = new NamedColor('Red', Color.BLACK, Color.RED) data = [ [name: 'Anthony', color: mediumBlue], [name: 'Greg', color: brightYellow], [name: 'Jeff', color: purple], [name: 'Murray', color: brightRed] ] // 控制 control swing = new SwingBuilder() frame = swing.frame(title: 'Table Demo'){ scrollPane { table(id: 'table'){ tableModel(list: data) { propertyColumn(header: 'Name', propertyName: 'name') propertyColumn(header: 'Color',propertyName: 'color', type:NamedColor) } } } } frame.pack() // view , 渲染层 swing.table.setDefaultRenderer(NamedColor, new ColorRenderer()) frame.visible = true class ColorRenderer extends JLabel implements TableCellRenderer{ ColorRenderer(){opaque = true} @Override Component getTableCellRendererComponent(JTable table, Object color, boolean isSelected, boolean hasFocus, int row, int column) { background = color.background foreground = color.foreground text = color.name horizontalAlignment=CENTER this } }
-