概要

  • このページは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上で扱う必要があるので、以下のサンプルでは、selfjava.lang.Runnablerunメソッドを実装し、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を追加)

インタフェースの実装(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_javarubyの配列を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で使用する

ソースコードの文字コード(エンコーディング)

# -*- 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 でOK?
    • 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形式のテキストをWiki形式(Google Project Hosting)のファイルに変換する

jruby -E UTF-8 p2w.rb ./wiki ../java-swing-tips-wiki

PukiWikiのbackupファイルから、公開日時を取得する

  • PukiWikibackupフォルダ以下にある.gzファイルから、そのファイルの公開日時を取得する
    • 一行目からUnixtimeを取得しているだけなので、履歴が$maxageを超えている場合は不正確になる
#!/usr/bin/env ruby
require 'fileutils'
require 'zlib'
require 'time'

#h = Hash.new
path = "/home/terai/s55.xrea.com/public_html/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

リンク

コメント