as(強制変換演算子)による無名クラスの代用

GroovyMagの今月号やSwingPadのソースみて勝手に驚いていたが,ウチ帰って「Grails徹底入門(asin:4798117366)」読み返してたら,ちゃんと書いてあった(p.72を参照)。


えー,何を驚いたかと言えば「クロージャやMapはas演算子を使う事でインターフェイスに変換できる」ということに驚いたのだよ。
つまり,(↓)こんなのとか,

def button = new JButton()
button.addActionListener({ println "action!!" } as ActionListener) 

(↓)こんなのはGroovy的にアリなんだそうな。

def panel = new JPanel()
panel.addMouseListener([mouseClicked: { println "clicked" }
                        mouseEntered: { println "entered" },
                        mouseExited: { println "exited" },
                        mouseReleased: { println "released" }] as MouseListener)


as演算子で指定する型は必ずしもインターフェイスである必要はないらしく,(↓)こんな風にアダプタを指定する事もできたよ。

def panel = new JPanel()
panel.addMouseListener([mouseClicked: { println "clicked" }
                        mouseReleased: { println "released" }] as MouseAdapter)

あーなんだよー。この事実にもっと早く気づいていればあのドラッグ&ドロップの例は,こんな風に書けたんだな。

import groovy.swing.SwingBuilder

import static javax.swing.WindowConstants.*
import static java.awt.dnd.DnDConstants.*
import static java.awt.datatransfer.DataFlavor.*

import javax.swing.DefaultListModel
import java.awt.dnd.*

def myList

def dropListener = [
  drop: {e ->
    e.acceptDrop(ACTION_COPY_OR_MOVE)
    myList.model.removeAllElements()
    try {
      if (e.isDataFlavorSupported(javaFileListFlavor)) {
        def trans = e.transferable
        trans.getTransferData(javaFileListFlavor).each {
          myList.model.addElement(it)
        }
      }
    } catch (ex) {
      e.dropComplete(false)
    }
  },
  dragEnter: {e ->
    e.acceptDrag(ACTION_COPY_OR_MOVE)
  }
] as DropTargetAdapter

SwingBuilder.build {
  frame(title: "DnD", pack: true, visible: true,
        defaultCloseOperation: EXIT_ON_CLOSE) {
    scrollPane() {
      myList = list(model: new DefaultListModel(),
                    dropTarget: new DropTarget(myList, ACTION_COPY_OR_MOVE,
                                               dropListener, true))
    }
  }
}

新しい構文覚えて小躍りするほどうれしかったんだけど,無名クラス使えりゃ,こんなトリック必要ないのかなともオモタ。まあ,こうゆう書き方も中二病的魅力があって面白いけどね。:-P
#そんなワケで昨日言った事は訂正しとこ。