2008-12-18 (Thu) [長年日記]

Re: はじめてのSwing on JRubyその弐

id:xibbarさんのところでJRubyチュートリアルっぽいことをしているので便乗してみます。

最後のSimpleGui1Bクラスは次のように書くと多少Rubyっぽく見えるかもしれません。

require 'java'
import javax.swing.JFrame
import javax.swing.JButton

class SimpleGui1B
  def initialize
    frame = JFrame.new
    button = JButton.new("click me")
    frame.default_close_operation = JFrame::EXIT_ON_CLOSE
    frame.content_pane.add(button)
    frame.setSize(300,300)
    frame.visible = true
    button.add_action_listener java.awt.event.ActionListener.impl { |method, e|
      e.source.text = "I've been clicked!"
    }
  end
end

SimpleGui1B.new

JRubyの場合、Javaインターフェースを直接実装したクラスを作らなくてもRubyのブロックを渡して実装クラスとすることができます。この場合、第1ブロック引数にはメソッド名が文字列で渡されます*1。第2のブロック引数にはイベント発生時に渡される情報(この場合java.awt.event.ActionListenerを実装したインスタンス)が渡されます。

Swingのイベントハンドラのようにメソッドがひとつしかない単純なインターフェースを持ったクラスがたくさん必要なプログラミングでは特に、Rubyの強力なブロック渡しを活用することで簡潔に書けますね。

またブロックはコンテキストを保持するため@buttonをインスタンス変数にする必要が無くなるのもポイントでしょうか。

追記12/19: @tom_eneboからインターフェースのimplメソッドは使わなくてよいと教えてもらったので、その場合のソースも書いておきます。より短くなりました。

require 'java'
import javax.swing.JFrame
import javax.swing.JButton

class SimpleGui1B
  def initialize
    frame = JFrame.new
    button = JButton.new("click me")
    frame.default_close_operation = JFrame::EXIT_ON_CLOSE
    frame.content_pane.add(button)
    frame.setSize(300,300)
    frame.visible = true
    button.add_action_listener { |e|
      e.source.text = "I've been clicked!"
    }
  end
end

SimpleGui1B.new

Tags: JRuby

*1 メソッド名をキーに処理をディスパッチするのに使えます。

本日のツッコミ(全1件) [ツッコミを入れる]
# xibbar (2008-12-19 (Fri) 09:11)

なかなかRuby的に書ける部分がわかんなかったりして、<br>それがハードルだったりしますよね。<br>JRubyの本無いのかしらなんて思ったけど、ないし。<br>このシリーズ、もうちょっと続けていくので、<br>できればフォローしていただけたら助かります。