JRuby のバックアップの現在との差分(No.13)
- バックアップ一覧
- 差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- JRuby へ行く。
- 1 (2012-09-25 (火) 20:14:36)
- 2 (2012-09-27 (木) 10:51:10)
- 3 (2012-09-27 (木) 15:37:20)
- 4 (2012-10-02 (火) 15:06:42)
- 5 (2012-10-02 (火) 16:57:35)
- 6 (2012-10-05 (金) 14:04:57)
- 7 (2012-10-24 (水) 15:37:38)
- 8 (2012-10-24 (水) 20:18:14)
- 9 (2012-10-26 (金) 18:56:41)
- 10 (2012-10-29 (月) 21:17:01)
- 11 (2012-11-16 (金) 18:40:36)
- 12 (2012-11-18 (日) 23:16:34)
- 13 (2012-11-23 (金) 04:33:39)
- 14 (2012-11-30 (金) 21:44:42)
- 15 (2012-12-06 (木) 01:11:58)
- 16 (2013-09-16 (月) 20:18:28)
- 17 (2013-09-17 (火) 14:24:43)
- 18 (2014-08-29 (金) 16:12:41)
- 19 (2014-09-02 (火) 15:42:27)
- 20 (2014-09-04 (木) 01:37:28)
- 21 (2014-09-19 (金) 15:58:36)
- 22 (2014-09-19 (金) 22:05:52)
- 23 (2014-09-26 (金) 19:03:10)
- 24 (2014-11-08 (土) 01:41:12)
- 25 (2015-09-29 (火) 19:47:58)
- 26 (2017-10-27 (金) 16:26:13)
- 27 (2019-02-19 (火) 14:03:07)
- 追加された行はこの色です。
- 削除された行はこの色です。
TITLE:JRuby #keywords(JRuby Swing) #description(JRubyでのSwingの使用方法や文字コードに関するメモなど) --- keywords: [JRuby, Swing, Java, Ruby] description: JRubyでのSwingの使用方法や文字コードに関するメモなど author: aterai pubdate: 2012-07-19 --- #contents * 概要 [#summary] - このページは`JRuby`で作成した`Swing`を使用するサンプルの一覧です。 //-- [[JRuby+Swing - てんぷらメモ@はてな>http://d.hatena.ne.jp/aterai/searchdiary?word=%2a%5bJRuby%5d]]から移動。 RIGHT:Posted by &author(aterai); at 2012-07-19 *JRuby で Swing などのサンプル [#ved1e336] - [[JRuby+Swing - てんぷらメモ@はてな>http://d.hatena.ne.jp/aterai/searchdiary?word=%2a%5bJRuby%5d]]から移動中。 #contents(big) * 概要 [#h838d289] 環境変数 JAVA_HOME, JRUBY_HOME を設定し、パスを通しておく。 ** 環境変数 [#JRUBY_HOME] 環境変数`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 サンプル [#f4745b09] ** EDT で起動(JFrameを表示) [#y2f124bd] - Swingのコンポーネントは Event Dispatch Thread 上で扱う必要があるので、以下のサンプルでは、self が java.lang.Runnable の runメソッドを実装し、java.awt.EventQueue.invokeLater で実行している - require "java" より include Java が良い? - %%import より java_import javax.swing.JLabel が良い?%% - 適当なファイル名で保存して、 jruby Hoge.rb などで実行 * Swing + JRuby サンプル [#sourcecode] ** EDT で起動(JFrameを表示) [#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`と実行 #code{{ include Java #gist(6579373) java_import javax.swing.JLabel java_import javax.swing.WindowConstants def create_and_show_GUI frame = javax.swing.JFrame.new "Title" frame.default_close_operation = WindowConstants::EXIT_ON_CLOSE frame.content_pane.add JLabel.new "Test" frame.set_size(320, 240) frame.location_relative_to = nil frame.visible = true end def run create_and_show_GUI end java.awt.EventQueue.invokeLater self }} ** 例外処理の記述方法(SystemLookAndFeelの設定) [#Exception] - `SystemLookAndFeel`を設定する際の例外処理を、`begin rescue`で記述する ** 例外処理の記述方法(SystemLookAndFeelの設定) [#ef47fd0c] - SystemLookAndFeel を設定する際の例外処理を、begin rescue で記述する #gist(6579399) #code{{ include Java ** クラスの継承(JPanelを継承) [#extend] - `class MainPanel < JPanel` java_import javax.swing.JScrollPane java_import javax.swing.JTree java_import javax.swing.UIManager java_import javax.swing.WindowConstants def create_and_show_GUI # try{ # UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); # }catch(Exception e) { e.printStackTrace(); } 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 frame = javax.swing.JFrame.new "Title" frame.default_close_operation = WindowConstants::EXIT_ON_CLOSE frame.content_pane.add JScrollPane.new(JTree.new) frame.set_size(320, 240) frame.location_relative_to = nil frame.visible = true end def run create_and_show_GUI end java.awt.EventQueue.invokeLater self }} #gist(6579429) ** クラスの継承(JPanelを継承) [#ga5f4479] - class MainPanel < JPanel #code{{ include Java java_import java.awt.Dimension java_import javax.swing.JPanel java_import javax.swing.JTextField class MainPanel < JPanel def initialize super field = JTextField.new 32 self.add field self.preferred_size = Dimension.new(320, 240) end end java_import javax.swing.UIManager java_import javax.swing.WindowConstants def create_and_show_GUI 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 frame = javax.swing.JFrame.new "Title" frame.default_close_operation = WindowConstants::EXIT_ON_CLOSE frame.content_pane.add MainPanel.new frame.pack frame.location_relative_to = nil frame.visible = true end def run create_and_show_GUI end java.awt.EventQueue.invokeLater self }} ** 無名インナークラス(JButtonにActionListenerを追加) [#vc5b32ac] - リスナーをJButtonに設定し、クリックするとJTextFieldに文字を追加 ** 無名インナークラス(JButtonにActionListenerを追加) [#AnonymousClasses] - リスナーを`JButton`に設定し、クリックすると`JTextField`に文字を追加 -- [http://jira.codehaus.org/browse/JRUBY-903 #JRUBY-903 Java interface modules - jira.codehaus.org] -- [http://jira.codehaus.org/browse/JRUBY-991 #JRUBY-991 Auto java interface coercion for vanilla ruby objects - jira.codehaus.org] --- implicit closure conversion --- `implicit closure conversion` -- [http://blog.nicksieger.com/articles/2006/12/01/rspec-jruby-mocking-and-multiple-interfaces RSpec, JRuby, Mocking, and Multiple Interfaces] -- %%[http://www.bloglines.com/blog/ThomasEEnebo?id=40 Exploring JRuby Syntax Trees in JRuby]%% -- [https://blogs.oracle.com/nishigaya/entry/tips_for_accessing_java_objects2 Javaインタフェースの実装にクロージャを使用する - Tips for accessing Java objects from JRuby (Part 3) (Nishigaya's Weblog)] #code{{ include Java #gist(6579457) java_import java.awt.Dimension java_import javax.swing.JPanel java_import javax.swing.JButton java_import javax.swing.JTextField ** インタフェースの実装(MouseListenerを追加) [#Interface] - `java_implements`はもう使用できない? -- 代わりに: `class MainPanel < JPanel; include MouseListener` -- カンマ区切りで複数指定しても可: `class MainPanel < JPanel; include MouseListener, ActionListener` - `instanceof` -- `self.java_kind_of?(MouseListener)` class MainPanel < JPanel def initialize super field = JTextField.new 32 button = JButton.new "add a" button.add_action_listener { |e| puts e field.text = field.text + "a" } self.add field self.add button self.preferred_size = Dimension.new(320, 240) end end #gist(6579526) java_import javax.swing.UIManager java_import javax.swing.WindowConstants def create_and_show_GUI 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 frame = javax.swing.JFrame.new "JRuby Swing JButton ActionListener" frame.default_close_operation = WindowConstants::EXIT_ON_CLOSE frame.content_pane.add MainPanel.new frame.pack frame.location_relative_to = nil frame.visible = true end def run create_and_show_GUI end java.awt.EventQueue.invokeLater self }} ** インタフェースの実装(MouseListenerを追加) [#sbceeeb6] - java_implements はもう使用できない? -- 代わりに class MainPanel < JPanel; include MouseListener -- カンマ区切りで複数指定しても可 class MainPanel < JPanel; include MouseListener, ActionListener - instanceof -- self.java_kind_of?(MouseListener) #code{{ # -*- encoding: utf-8 -*- include Java java_import java.awt.event.MouseListener java_import java.awt.Dimension java_import javax.swing.JPanel java_import javax.swing.JButton java_import javax.swing.JTextField class MainPanel < JPanel include MouseListener def initialize super field = JTextField.new 32 button = JButton.new "add a" button.add_action_listener { field.text = field.text + "a" } # # https://blogs.oracle.com/nishigaya/entry/tips_for_accessing_java_objects2 # button.add_mouse_listener do |ev| # p ev # end # #:1 warning: singleton on non-persistent Java type #<Class:0x103bdaa8> (http://wiki.jruby.org/Persistence) # class << listener = java.awt.event.MouseListener.new # def mouseEntered(e) # puts "mouseEntered" # end # def mouseExited(e) # puts "mouseExited" # end # def mousePressed(e) # puts "mousePressed" # end # def mouseClicked(e) # puts "mouseClicked" # end # def mouseReleased(e) # puts "mouseReleased" # end # end # button.add_mouse_listener listener # puts self.java_kind_of?(MouseListener) button.add_mouse_listener self self.add field self.add button self.preferred_size = Dimension.new(320, 240) end # MouseListener def mouseEntered(e) puts "mouseEntered" end def mouseExited(e) puts "mouseExited" end def mousePressed(e) puts "mousePressed" end def mouseClicked(e) puts "mouseClicked" end def mouseReleased(e) puts "mouseReleased" end end java_import javax.swing.UIManager java_import javax.swing.WindowConstants def create_and_show_GUI 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 frame = javax.swing.JFrame.new "JRuby Swing JButton ActionListener" frame.default_close_operation = WindowConstants::EXIT_ON_CLOSE frame.content_pane.add MainPanel.new frame.pack frame.location_relative_to = nil frame.visible = true end def run create_and_show_GUI end java.awt.EventQueue.invokeLater self }} ** オーバーライドしたメソッドでsuperクラスのメソッドを呼び出すと例外が発生する [#l5cc4e22] ** オーバーライドしたメソッドでsuperクラスのメソッドを呼び出すと例外が発生する [#Override] Exception in thread "AWT-EventQueue-0" org.jruby.exceptions.RaiseException: (NoMethodError) undefined method `paintComponent' for nil:NilClass -参考: [http://markmail.org/message/oxpqjwpfo74fdr3j Re jruby-user Error when calling protected method paintComponent in Java Swing superclass - Bill Dortch - org.codehaus.jruby.user - MarkMail] - 参考: [http://markmail.org/message/oxpqjwpfo74fdr3j Re jruby-user Error when calling protected method paintComponent in Java Swing superclass - Bill Dortch - org.codehaus.jruby.user - MarkMail] SuperPaint = JComponent.java_class.declared_method 'paintComponent', 'java.awt.Graphics' などとして、関数ポインタ?を作成して実行する。 #code{{ # -*- encoding: utf-8 -*- include Java java_import java.awt.Color java_import java.awt.EventQueue java_import java.awt.Font java_import java.awt.RenderingHints java_import java.awt.event.ActionListener java_import java.awt.font.FontRenderContext java_import java.awt.font.TextLayout java_import javax.swing.JComponent java_import javax.swing.JFrame java_import javax.swing.JPanel java_import javax.swing.UIManager java_import javax.swing.WindowConstants #gist(6579618) class MainPanel < JPanel include ActionListener def initialize super self.font = Font.new "serif", Font::PLAIN, 100 @text = "JRuby Swing JPanel paintComponent Marquee Animation" @frc = FontRenderContext.new nil, true, true @tl = TextLayout.new @text, self.font, @frc @b = @tl.bounds @yy = @tl.ascent/2 + @b.y @xx = 0 javax.swing.Timer.new(10, self).start self.preferred_size = java.awt.Dimension.new 320, 240 end SuperPaint = JComponent.java_class.declared_method 'paintComponent', 'java.awt.Graphics' def paintComponent(g) #XXX: super.paintComponent g SuperPaint.invoke self.java_object, g.java_object g.setRenderingHint RenderingHints::KEY_TEXT_ANTIALIASING, RenderingHints::VALUE_TEXT_ANTIALIAS_ON g.setRenderingHint RenderingHints::KEY_ANTIALIASING, RenderingHints::VALUE_ANTIALIAS_ON g.color = Color::WHITE g.drawLine 0, self.height/2, self.width, self.height/2 g.color = Color::BLACK g.font = self.font g.drawString @text, self.width-@xx, self.height/2-@yy @xx = (self.width+@b.width-@xx > 0) ? @xx+2 : 0 end def actionPerformed(e) self.repaint end end ** 配列(JTableに行追加) [#Array] - `["No.", "Name", "Path"].to_java`で`ruby`の配列を`java`の配列に変換して、`JTable`の行を追加 def create_and_show_GUI 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 frame = JFrame.new "JRuby Swing Marquee Animation" frame.default_close_operation = WindowConstants::EXIT_ON_CLOSE frame.content_pane.add MainPanel.new frame.pack frame.location_relative_to = nil frame.visible = true end #gist(6579639) def run; create_and_show_GUI; end EventQueue.invokeLater self }} ** 配列(JTableに行追加) [#x41f0fcd] - ["No.", "Name", "Path"].to_java でrubyの配列をjavaの配列に変換 #code{{ # -*- encoding: utf-8 -*- include Java java_import javax.swing.UIManager java_import javax.swing.WindowConstants java_import javax.swing.table.DefaultTableModel def make_ui m = DefaultTableModel.new(nil, ["No.", "Name", "Path"].to_java) m.add_row java.util.Vector.new(["テスト", "あああ", "いいいい"]) m.add_row ["aaa", "bbb", "ccc"].to_java t = javax.swing.JTable.new m p = javax.swing.JPanel.new java.awt.BorderLayout.new p.add javax.swing.JScrollPane.new(t) 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 "jruby swing" 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 }} ** protected なメソッドをオーバーライドして使用 [#ye59d71e] - protected なメソッドをオーバーライドして使用できなかった -- JRuby 1.2.0で修正? ** protected なメソッドをオーバーライドして使用 [#protected] - `protected`なメソッドをオーバーライドして使用できなかった -- `JRuby 1.2.0`で修正? --- [http://jira.codehaus.org/browse/JRUBY-2861 JRUBY-2861 Cannot call super inside a method that overrides a protected method on Java base class] - SwingWorker#process がオーバーライドして使用(firePropertyChange を使用しなくて済む) -- http://terai.xrea.jp/data/jruby/swing-worker3.rb - `SwingWorker#process`がオーバーライドして使用(`firePropertyChange`を使用しなくて済む) //-- https://ateraimemo.com/data/jruby/swing-worker3.rb - `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` - 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 #gist(6590330) #code{{ # -*- encoding: utf-8 -*- include Java java_import java.awt.BorderLayout java_import java.awt.Color java_import java.awt.Dimension java_import java.util.Random java_import java.util.Vector java_import java.util.concurrent.Executors java_import javax.swing.BorderFactory java_import javax.swing.JButton java_import javax.swing.JPanel java_import javax.swing.JProgressBar java_import javax.swing.JScrollPane java_import javax.swing.JTable java_import javax.swing.SwingWorker java_import javax.swing.table.DefaultTableCellRenderer java_import javax.swing.table.DefaultTableModel java_import javax.swing.table.TableCellRenderer PROGRESS_IDX = 2 class TestModel < DefaultTableModel @@number = 0 @@columns = { :name=>["No.", "Name", "Progress"], :editable=>[false, false, false], :class=>[java.lang.Integer, java.lang.String, java.lang.Integer], } def add_test(test) self.add_row Vector.new([@@number, test.tname, test.progress]) #self.add_row [@@number, test.tname, test.progress].to_java @@number = @@number+1 end def getColumnCount return @@columns[:name].size end def getColumnName(modelIndex) return @@columns[:name][modelIndex] end def isCellEditable(row, col) return @@columns[:editable][col] end def getColumnClass(modelIndex) return @@columns[:class][modelIndex] end end class Test attr_accessor :tname attr_accessor :progress def initialize(tname = nil, progress = 0) self.tname = tname self.progress = java.lang.Integer.new(progress) end end class MainPanel < JPanel def initialize super BorderLayout.new model = TestModel.new model.add_test Test.new("aaaa", 100) table = JTable.new model table.auto_create_row_sorter = true table.fills_viewport_height = true table.show_horizontal_lines = false table.show_vertical_lines = false table.intercell_spacing = Dimension.new table.put_client_property "terminateEditOnFocusLost", true column = table.column_model.column 0 column.max_width = 60 column.min_width = 60 column.resizable = false column = table.column_model.column PROGRESS_IDX bar = JProgressBar.new 0, 100 bar.border = BorderFactory.createEmptyBorder 1,1,1,1 renderer = table.get_default_renderer java.lang.Object column.set_cell_renderer do |table, obj, isSelected, hasFocus, row, column| text = "Done" if obj<0 text = "Canceled" elsif obj<100 bar.value = obj return bar end return renderer.getTableCellRendererComponent( table, text, isSelected, hasFocus, row, column) end executor = Executors.new_cached_thread_pool; button = JButton.new "add dummy task" button.add_action_listener do worker = ProgressWorker.new model #worker.addPropertyChangeListener ProgressListener.new(model) model.add_test Test.new("example", 0) worker.execute #executor.execute worker #JDK 1.6.0_18 end self.add button, BorderLayout::SOUTH self.add JScrollPane.new(table) self.preferred_size = Dimension.new 320, 240 end end class ProgressWorker < SwingWorker attr_accessor :model def initialize(model) super() @model = model @key = model.row_count @sleepDummy = 0.1 @lengthOfTask = Random.new.nextInt(60) + 1 end def doInBackground prev = 0 current = 0 while current<@lengthOfTask && !self.cancelled? current = current + 1 begin sleep @sleepDummy rescue InterruptedException => e proxied_e = JavaUtilities.wrap e.cause proxied_e.print_stack_trace self.publish [-1].to_java(:Integer) break end #puts "#{@key}: #{i}" i = 100*current/@lengthOfTask self.publish [i].to_java :Integer #self.firePropertyChange("progress", prev, i) ##self.publish i prev = i end return @sleepDummy*@lengthOfTask end def process(chunks) chunks.each {|i| #@model.set_value_at i, @key, PROGRESS_IDX #Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: # java.lang.Byte cannot be cast to java.lang.Long @model.set_value_at java.lang.Integer.new(i), @key, PROGRESS_IDX } end def done text = nil i = -1 if self.cancelled? text = "Canceled" else begin i = self.get text = "Done" rescue Exception => e text = "InterruptedException" proxied_e = JavaUtilities.wrap e.cause proxied_e.print_stack_trace end end puts "#{@key}: #{text} : #{i}s" end end import javax.swing.UIManager import javax.swing.WindowConstants def create_and_show_GUI 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 frame = javax.swing.JFrame.new "JRuby Swing JTable" frame.default_close_operation = WindowConstants::EXIT_ON_CLOSE frame.content_pane.add MainPanel.new frame.pack frame.location_relative_to = nil frame.visible = true end def run; create_and_show_GUI; end java.awt.EventQueue.invokeLater self }} ** JRubyでリソース(URL)のエントリを取得してSwingで使用する [#cd7f9169] - [[JRubyでリソース(URL)のエントリを取得してSwingで使用する>JRuby/Resource]] ** ソースコードの文字コード(エンコーディング) [#k09b3d13] - 1.7.0以前?は、*.rbの文字コードはUTF-8固定だった? - 1.7.0から?は、ソースコードの先頭にマジックコメント ** ソースコードの文字コード(エンコーディング) [#encoding] - `1.7.0`以前?は、`*.rb`の文字コードは`UTF-8`固定だった? - `1.7.0`から?は、ソースコードの先頭にマジックコメント -- [http://d.hatena.ne.jp/Artisan/20110409/1302326813 Ruby1.9にしたら invalid multibyte char (US-ASCII) - 屑プログラマの憂鬱] #code{{ # -*- 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 などのサンプル [#j67b4b82] * その他、JRuby + One-Liner などのサンプル [#OneLiner] ** JRuby One-Liner で、UIManagerのDefaults.keySetを一覧表示する [#zdaf3499] ** JRuby One-Liner で、UIManagerのDefaults.keySetを一覧表示する [#UIManager] > jruby -rjava -e "javax.swing.UIManager.lookAndFeelDefaults.keySet.each{|o| puts o}" ** One-Liner での文字コード [#ze146211] ** One-Liner での文字コード [#CodePoint] > 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 - 参考: [http://jp.rubyist.net/magazine/?0025-Ruby19_m17n Rubyist Magazine - Ruby M17N の設計と実装] ** JRuby 1.7.0.preview1 でArgumentErrorが発生する場合 [#n2494e41] - 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」と同じ?%% ** Unixtimeをiso8601形式の文字列に変換 [#TIME] > 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が発生する場合 [#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」の方が良さそう - `JRuby 1.7.0.preview2`では、`-E UTF-8`の方が良さそう #code{{ 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 のファイル名をデコード [#v3f63eba] ** JRuby で PukiWiki のファイル名をデコード [#PukiWikiFileName] - 参考: [http://homepage1.nifty.com/~tetsu/ruby/cmd/ll.html Ruby: ll (ls -l) command (Japanese)] #code{{ 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*')}" ** PukiWiki形式のテキストをMarkdown形式のファイルに変換する [#ce127298] ** JRuby で PukiWiki のファイル名にエンコード [#PukiWikiFileEncode] > jruby -pe 'gsub(/^([0-9]+)\t(.+)$/){[$1,$2.gsub(/./){|x|x.ord.to_s(16).upcase}].join("\t")}' cache/recent.dat ** PukiWiki形式のテキストをMarkdown形式のファイルに変換する [#PukiWikiMarkdown] [[PukiWiki形式のテキストをMarkdown形式のファイルに変換する>JRuby/PukiWiki2Markdown]]に移動 * リンク [#f74d094d] // ** PukiWiki形式のテキストをWiki形式(Google Project Hosting)のファイルに変換する [#xc0d624b] // - [[PukiWiki形式のテキストをMarkdown形式のファイルに変換する>JRuby/PukiWiki2Markdown]]を改変して、`PukiWiki`形式のテキストファイルを、`Google Project Hosting`の`Wiki`形式ファイルに変換 // // jruby -E UTF-8 p2w.rb ./wiki ../java-swing-tips-wiki // // - [https://ateraimemo.com/data/jruby/p2w.rb p2w.rb] // -- https://code.google.com/p/java-swing-tips/w/list // -- [http://code.google.com/p/support/wiki/WikiSyntax WikiSyntax - support - The reference to the wiki syntax for Google Code projects - User support for Google Project Hosting - Google Project Hosting] // -- どちらも`Wiki`なので、変換はとても簡単 // -- `ArrowButton`, `BorderFactory`などが自動リンクになってしまう ** PukiWikiのbackupファイルから、公開日時を取得する [#PukiWikiBkup] - `PukiWiki`の`backup`フォルダ以下にある`.gz`ファイルから、そのファイルの公開日時を取得する -- 一行目から`Unixtime`を取得しているだけなので、履歴が`$maxage`を超えている場合は不正確になる #code{{ #!/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 }} * 参考リンク [#reference] - [http://www.rubyinside.com/jruby-swt-future-cross-platform-ruby-desktop-app-development-298.html JRuby + SWT = Future Cross Platform Ruby Desktop App Development?] -- JRuby + SWT サンプル -- `JRuby` + `SWT`サンプル -- via [http://www.javalobby.org/java/forums/t84113.html:title=Frankengui? Using SWT and Ruby for your GUIs] * コメント [#id3843ca] * コメント [#comment] #comment #comment