JRuby
Total: 13870
, Today: 2
, Yesterday: 2
Posted by aterai at
Last-modified:
概要
- このページは
JRuby
で作成したSwing
を使用するサンプルの一覧です。
環境変数
環境変数JAVA_HOME
, JRUBY_HOME
を設定し、パスを通しておく。
> set JAVA_HOME=C:\Program Files\Java\jdk1.7.0_04 > set JRUBY_HOME=C:\jruby-1.7.0 > set Path=%JAVA_HOME%\bin;%JRUBY_HOME%\bin;%Path% > jruby -version jruby 1.7.0 (1.9.3p203) 2012-10-22 ff1ebbe on Java HotSpot(TM) 64-Bit Server VM 1.7.0_09-b05 [Windows 7-amd64]
Swing + JRuby サンプル
EDT で起動(JFrameを表示)
Swing
のコンポーネントはEvent Dispatch Thread
上で扱う必要があるので、以下のサンプルでは、self
がjava.lang.Runnable
のrun
メソッドを実装し、java.awt.EventQueue.invokeLater
で実行しているrequire "java"
よりinclude Java
が良い?import
よりjava_import javax.swing.JLabel
が良い?jruby EDTSwingTest.rb
と実行
例外処理の記述方法(SystemLookAndFeelの設定)
SystemLookAndFeel
を設定する際の例外処理を、begin rescue
で記述する
クラスの継承(JPanelを継承)
class MainPanel < JPanel
無名インナークラス(JButtonにActionListenerを追加)
- リスナーを
JButton
に設定し、クリックするとJTextField
に文字を追加- #JRUBY-903 Java interface modules - jira.codehaus.org
- #JRUBY-991 Auto java interface coercion for vanilla ruby objects - jira.codehaus.org
implicit closure conversion
- RSpec, JRuby, Mocking, and Multiple Interfaces
Exploring JRuby Syntax Trees in JRuby- Javaインタフェースの実装にクロージャを使用する - Tips for accessing Java objects from JRuby (Part 3) (Nishigaya's Weblog)
インタフェースの実装(MouseListenerを追加)
java_implements
はもう使用できない?- 代わりに:
class MainPanel < JPanel; include MouseListener
- カンマ区切りで複数指定しても可:
class MainPanel < JPanel; include MouseListener, ActionListener
- 代わりに:
instanceof
self.java_kind_of?(MouseListener)
オーバーライドしたメソッドでsuperクラスのメソッドを呼び出すと例外が発生する
Exception in thread "AWT-EventQueue-0" org.jruby.exceptions.RaiseException: (NoMethodError) undefined method `paintComponent' for nil:NilClass
SuperPaint = JComponent.java_class.declared_method 'paintComponent', 'java.awt.Graphics'
などとして、関数ポインタ?を作成して実行する。
配列(JTableに行追加)
["No.", "Name", "Path"].to_java
でruby
の配列をjava
の配列に変換して、JTable
の行を追加
protected なメソッドをオーバーライドして使用
protected
なメソッドをオーバーライドして使用できなかったSwingWorker#process
がオーバーライドして使用(firePropertyChange
を使用しなくて済む)JDK 1.6.0_18
で、TableRowSorter
でのソートが不正な件は、JDK 1.6.0_2x
で修正済Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.Byte cannot be cast to java.lang.Long
JRubyでリソース(URL)のエントリを取得してSwingで使用する
ソースコードの文字コード(エンコーディング)
1.7.0
以前?は、*.rb
の文字コードはUTF-8
固定だった?1.7.0
から?は、ソースコードの先頭にマジックコメント
# -*- encoding: utf-8 -*-
include Java
java_import javax.swing.UIManager
java_import javax.swing.WindowConstants
java_import javax.swing.table.DefaultTableModel
def make_ui
p = javax.swing.JPanel.new java.awt.BorderLayout.new
p.add javax.swing.JLabel.new("日本語")
return p
end
def run #Override
begin
UIManager.look_and_feel = UIManager.system_look_and_feel_class_name
rescue Exception => e
proxied_e = JavaUtilities.wrap e.cause
proxied_e.print_stack_trace
end
f = javax.swing.JFrame.new "タイトル"
f.default_close_operation = WindowConstants::EXIT_ON_CLOSE
f.content_pane.add make_ui
f.set_size(320, 240)
f.location_relative_to = nil
f.visible = true
end
java.awt.EventQueue.invoke_later self
その他、JRuby + One-Liner などのサンプル
JRuby One-Liner で、UIManagerのDefaults.keySetを一覧表示する
> jruby -rjava -e "javax.swing.UIManager.lookAndFeelDefaults.keySet.each{|o| puts o}"
One-Liner での文字コード
> chcp 現在のコード ページ: 932
> jruby -J-Dfile.encoding=UTF-8 -rjava -e "puts java.net.URLEncoder.encode('日本語','UTF-8')" > jruby -J-Dfile.encoding=UTF-8 -rjava -e 'puts java.net.URLEncoder.encode(""日本語"",""UTF-8"")' > jruby --1.9 -U -rjava -e "puts java.net.URLEncoder.encode('日本語','UTF-8')" > jruby -J-Dfile.encoding=UTF-8 -ruri -e "puts URI.encode('日本語')" > jruby -ruri -e "puts URI.encode('日本語'.encode('UTF-8'))" %E6%97%A5%E6%9C%AC%E8%AA%9E
> jruby --1.9 -rjava -e "puts java.net.URLEncoder.encode('日本語','MS932')" > jruby --1.9 -ruri -e "puts URI.encode_www_form_component('日本語')" > jruby -ruri -e "puts URI.encode('日本語')" %93%FA%96%7B%8C%EA
Unixtimeをiso8601形式の文字列に変換
> jruby -pe "gsub(/^[0-9]+/) {|x| Time.at(x.to_i)}" cache/recent.dat 2014-09-08 14:31:51 +0900 JRuby/PukiWiki2Markdown ... > jruby -r time -pe "gsub(/^[0-9]+/) {|x| Time.at(x.to_i).iso8601}" cache/recent.dat 2014-09-08T14:31:51+09:00 JRuby/PukiWiki2Markdown ...
JRuby 1.7.0.preview1 でArgumentErrorが発生する場合
JRuby 1.7.0.preview1
で以下のようなArgumentError
が発生する場合、-J-Dfile.encoding=UTF-8
を指定?set LANG=ja_JP.UTF-8
は、JRuby
では効果がない?-J-Dfile.encoding=UTF-8
は-E UTF-8
と同じ?
>jruby -v jruby 1.7.0 (1.9.3p203) 2012-10-22 ff1ebbe on Java HotSpot(TM) 64-Bit Server VM 1.7.0_09-b05 [Windows 7-amd64] >chcp 現在のコード ページ: 932 >jruby -J-Dfile.encoding=UTF-8 -ruri -e "puts URI.encode('日本語')" %E6%97%A5%E6%9C%AC%E8%AA%9E >jruby -E UTF-8 -ruri -e "puts URI.encode('日本語')" %93%FA%96%7B%8C%EA
JRuby 1.7.0.preview2
では、-E UTF-8
の方が良さそう
lines = src.rstrip.split(/\r?\n/).map {|line| line.chomp }
C:\pukiwiki2markdown>jruby p2m.rb wiki ArgumentError: invalid byte sequence in Windows-31J split at org/jruby/RubyString.java:4643 to_html at p2m.rb:45 main at p2m.rb:219 each at org/jruby/RubyArray.java:1611 main at p2m.rb:214 (root) at p2m.rb:234
C:\pukiwiki2markdown>jruby -J-Dfile.encoding=UTF-8 p2m.rb wiki wiki/2010-04-12-swing-leaftreecelleditor.markdown wiki/2007-06-18-swing-leftclippedcombobox.markdown ... C:\pukiwiki2markdown>jruby -E UTF-8 p2m.rb wiki wiki/2011-07-18-swing-listmouseselection.markdown ...
JRuby で PukiWiki のファイル名をデコード
if ARGV[0] == nil then
while line = STDIN.gets
STDOUT.puts "#{line.gsub!(/[A-F\d]{2}/) {|x| [x.hex].pack('C*')} }"
end
else
Dir::glob("*.#{ARGV[0]}").each {|f|
puts "#{f.gsub!(/[A-F\d]{2}/) {|x| [x.hex].pack('C*')} }"
}
end
> ls *.txt | jruby decode.rb > ls *.txt | jruby -pe "$_.gsub!(/[A-F\d]{2}/) {|x| [x.hex].pack('C*')}"
JRuby で PukiWiki のファイル名にエンコード
> jruby -pe 'gsub(/^([0-9]+)\t(.+)$/){[$1,$2.gsub(/./){|x|x.ord.to_s(16).upcase}].join("\t")}' cache/recent.dat
PukiWiki形式のテキストをMarkdown形式のファイルに変換する
PukiWiki形式のテキストをMarkdown形式のファイルに変換するに移動
PukiWikiのbackupファイルから、公開日時を取得する
PukiWiki
のbackup
フォルダ以下にある.gz
ファイルから、そのファイルの公開日時を取得する- 一行目から
Unixtime
を取得しているだけなので、履歴が$maxage
を超えている場合は不正確になる
- 一行目から
#!/usr/bin/env ruby
require 'fileutils'
require 'zlib'
require 'time'
#h = Hash.new
path = "/tmp/pukiwiki/backup"
Dir::foreach(path) do |f|
next if f == "." or f == ".." or !f.end_with?(".gz")
ap = "#{path}/#{f}"
Zlib::GzipReader.open(ap) do |gz|
n = f.sub(/\.gz$/, "").gsub(/[A-F\d]{2}/){|x|[x.hex].pack('C*')}
t = gz.gets.sub(/^[>]+ ?[0-9]* /, "") #一行目から日時を取得
x = Time.at(t.to_i).iso8601
puts "#{n}\t#{x}"
#h.store(n, x)
gz.close
end
end
参考リンク
- JRuby + SWT = Future Cross Platform Ruby Desktop App Development?
JRuby
+SWT
サンプル- via Using SWT and Ruby for your GUIs