JRubyのSwingサンプル swing2.rb
今までJRubyの中身自体について、ほとんど見てこなかったので、昨日のエントリで最後に動作確認として実行した、swing2.rbについて少し見てみます。シンプルですが、いくつかのJRubyの基本が学べるので、現時点ではちょうどいい教材です。
# Import Java packages include Java import javax.swing.JFrame frame = JFrame.new("Hello Swing") button = javax.swing.JButton.new("Klick Me!") class ClickAction include java.awt.event.ActionListener def actionPerformed(evt) javax.swing.JOptionPane.showMessageDialog(nil, <<EOS) <html>Hello from <b><u>JRuby</u></b>.<br> Button '#{evt.getActionCommand()}' clicked. EOS end end button.add_action_listener(ClickAction.new) # Add the button to the frame frame.get_content_pane.add(button) # Show frame frame.set_default_close_operation(JFrame::EXIT_ON_CLOSE) frame.pack frame.visible = true
さて、では最初の要素から順番に見ていきましょう。
# Import Java packages include Java
まず、JRubyを使うときは、Javaパッケージをincludeします。
import javax.swing.JFrame
Javaのパッケージは、Java言語と同様にimportで行います。(ただ、Ruby文法的には少し違和感がありますね。シンタックス・シュガーとなっているようです。jirbで調べられそうです。)
frame = JFrame.new("Hello Swing") button = javax.swing.JButton.new("Klick Me!")
Javaオブジェクトを生成し、Rubyの変数として代入しています。
class ClickAction include java.awt.event.ActionListener def actionPerformed(evt) javax.swing.JOptionPane.showMessageDialog(nil, <<EOS) <html>Hello from <b><u>JRuby</u></b>.<br> Button '#{evt.getActionCommand()}' clicked. EOS end end button.add_action_listener(ClickAction.new)
Javaで言うところの内部クラスですね。JRubyでは、Javaのインターフェースを宣言するときに、Rubyのincludeを利用します。これは、Javaが多重継承を許可しないため、言語間の差異を調整するものだと思います。
showMessageDialogメソッドは、Javaのものですが、メッセージ部分にヒアドキュメントと埋め込み評価式が使われているのがRubyっぽいですね。Javaに慣れている自分から見ると、不思議な感じがします。
# Add the button to the frame frame.get_content_pane.add(button) # Show frame frame.set_default_close_operation(JFrame::EXIT_ON_CLOSE) frame.pack frame.visible = true
あとは、Swingでお決まりの流れになっています。set_default_close_operationの引数にJFrameの定数を取っていますが、Rubyの文法に従いダブルコロンで表現されています。
このサンプルでは、JRubyのメリットが感じられるのはヒアドキュメントの部分くらいですが、このサンプルの最大の意味は「Javaとこれだけ親和性があるよ」ということが簡単に理解できる、というところでしょう。基本的に、JavaでできることをJRubyでやっても、あまり意味はないですから。
それよりも、おそらくJavaアプリケーションでも複雑なものを構築していくと、どうしてもメタプログラミング的なことをやらないといけなくなりますが、そのような場合までいって初めて、JRubyのRuby部分の柔軟性がメリットとして見えてくると思います。