第十一章、groovy的建造模式

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、理解建造概念

  1. 方法名就是节点名称(第一个方法根节点)
  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
          }
      }
      

上一篇:使用idea的groovy脚本自动创建MybatisPlus的实体


下一篇:springboot集成spock进行单元测试