1998年にSwingがJREのバージョン1.2に追加されると、その前身であるAWTは重要なアプリケーションにとって不十分なものとなった。Swingの(パフォーマンスとルックアンドフィールに次ぐ)問題の1つは、小さなアプリケーションを構築するのにも必要なコードの量(が多いこと)だ。この問題によってXMLベースのGUI定義言語(source)が作られることになった。
JRubyの有効性は今、(J)Rubyの言語機能を利用してSwingアプリケーション開発の単調さを軽減するライブラリという、別の動きを始めている。ブロックはイベントリスナーの定型文を避けるのに利用され、ビルダーのコンセプトはRubyコードの中の複雑にネストしたGUIを作成するために利用される。
最新のAPIは(Zed Shaw氏によるProfligacy(サイト・英語)だ。その焦点は、AWTとSwingのイベントリスナーのために必要なすべての定型文を避けて、イベントの取り扱いをより簡単にすることにある。コンポーネントの作成とセットアップは、その一方で、単純なJRubyコードと全く同じように見える。例えば、newで新しいSwingのウィジェットを作成するように。以下にProfligacyコードのサンプルを記す。(原文・英語)
@ui = Swing::Build.new JFrame, :texts, :label do |c,i|
c.texts = [JTextField.new(10), JTextField.new(10)]
c.texts.each_with_index {|t,n|
t.action_command = "text#{n}"
}
c.label = JLabel.new "Something will show up here."
i.texts = {:action => method(:text_action) }
end
@ui.layout = FlowLayout.new
@ui.build("Two Text Fields Demo").default_close_operation = JFrame::EXIT_ON_CLOSE
def text_action(type, event)
puts "EVENT: #{type} #{event.action_command}"
end
より多くのサンプルコードはリンクを参照。
Bill Dortch氏によるCheri::Swing(サイト・英語)は、ビルダーアプリケーションを作成するためのフレームワークであるCheri projectの一部だ。ビルダーは非常に少ないRubyコードで、階層的な構造の作成を可能にする。
menu_bar {
menu('File') {
mnemonic :VK_F
menu_item('Exit') {
mnemonic :VK_X
on_click { @frame.dispose }
}
}
}
これはRubyのmethod_missing(メソッドが定義されていないときに呼び出される)とブロックが、いくらかの非常にコンパクトなコードで1つのメニュー項目を含むメニューを持つメニューバーから構成されるコンポーネントツリーの作成を可能にするために、どのように利用されるかを示している。メソッドの呼び出しはすべて、実行されるブロック(中括弧の中のコード)を取る。メタプログラミングとmethod_missingの組み合わせは、新しいオブジェクトを作成するかどうかや、作成されたばかりのオブジェクトのニーモニックのようなメソッドを実行するかどうかの決定に利用される。on_clickの呼び出しに見られるように、Cheri::Swingは簡単なイベントの取り扱いもまた可能にする。on_clickはこのメニュー項目がクリックされたときに実行されるブロックを取り、すべての単調なイベントリスナーやアクションのセットアップを隠蔽する。
Jean Lazarou氏による実験的なSwiby(サイト・英語)は、JRubyのDSLとして(以前はF3として知られていた)JavaFXスクリプトを複製する。それはビルダーのコンセプトを利用してGUIを作成し、さらにJavaFXスクリプトのようにbind演算子を取る。これは変数の1つの参照が再代入されるたびに評価される式の定義を可能にする。これはコンパクトな方法でイベントの取り扱いを処理する。サンプルを以下に記す。
require 'swiby'
class HelloWorldModel
attr_accessor :saying
end
model = HelloWorldModel.new
model.saying = "Hello World"
Frame {
title "Hello World F3"
width 200
content {
Label {
text bind(model,:saying)
}
}
visible true
}
これらのAPIのどれか1つが何らかの意味を持つようになるかはまだ分からない。XMLでSwingのGUIを定義するライブラリはありふれたもの(source)で、新たに作成されるものは終わりが見えない。それらとの違いはJRubyライブラリが一般にとても小さいことで、Profligacyの場合はサードパーティに依存せず、現在のところコードは200行だ。これは、それらの理解とメンテナンスを容易にする。なので、それらすべてがRubyでGUIの定義を書くことを可能にし、それらはまたとても拡張しやすい。もしいくつかの機能やコンポーネントの組み合わせがサポートされないなら、機能の追加をライブラリのメンテナに働きかけなければならない代わりに、Swingオブジェクトの正しい取り扱いにフォールバックが可能だ。
あなたはどのアプローチでRubyのGUIコードを書くことを好むか?
(原文は2007年7月6日にリリースされました)