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
#そんなワケで昨日言った事は訂正しとこ。