Swing しましょ

長年ご愛用のママチャリがパンクした。空気を入れて10mも走ると、クッション性が失われて 地面のでこぼこがもろに体感出来る。空気入れ口の所のナットが緩んでいるかと思って点検 するも、緩みは無い。

以前お世話になったチャリ屋へ曳航したよ。親父さんが一人暇そうにしてた。後輪がいくら 空気を入れてもすぐ抜けちゃうんです。パンクとは言わなかったよ。だって、証拠を掴んで いないもの。熱があるので医者へ行って、風邪なんですと自己見立てによる誘導はやめま しょう、と一緒の事だな。

親父さん、空気を入れてからタイヤを撫でてたよ。やおら、へらみたいな道具でタイヤを こじあけて中のチューブを取り出すと、ひょいと自分の唾をチューブにぬった。そこから 泡泡してた。パンクだね。でも、それだけでは終わらなかった。今度はタイヤを擦り擦り。 そして、おいらに向かって、ここ見てみなと、タイヤの一部を指し示した。長年の使用で タイヤが磨り減って、反対側が見えるぐらいになってた。パンクを直してもまた直ぐに パンクするよ。タイヤとチューブを交換するしかないとの事。

幾らになりますか? 部品と工賃を入れて4000円だよ。即決でお願いしますと返答。 だって、carしない日は有っても(注 Lispにあらず)、チャリに乗らない日は無いぐらい の必需品だから。。 作業に30ぐらいかかるとの事だったので、チャリを預けてきた。

後で取りに行ったけど、ブレーキのキーキー音も直してくれていた。いい親父さんだなあ。 プロ中のプロだよ。

知人にこの事を話すと、後輪のパンク修理はチェーンを外すとかあって面倒だそうだ。 普通は5000円以上するよと言われた。ほんとうにチャリが好きなんだな。日曜日は店を閉めて ロードレースに行っちゃうような人だもの。サイクリング用の自転車って幾らぐらいから あるんですか? 上を見ればきりが無いようですけど、って、聞いてみたら、まあ8万も 出せば十分との事。余り商売っ気が無いのも好感。

Swing on FreeBSD

2回も続けて、ちと辛気くさい臨場なんて事をやってしまったので、心機一転、ぱーと やりたいね、なんて事を考えていたんだ。 そしたら、更に過去を思い出しちゃったよ。

以前、FreeBSDにDDDを入れた時、ちょっとおっかなびっくりだったんだ。だって、GUIの アプリって、土台に何を使ってるかで大幅にコンパイル時間が変わるからだ。Qtなんか 使われてた日にゃ、根こそぎコンパイルさせられるはめになる。そんな訳で、先にArchLinux で試して(lddで何をリンクしてるか確認)いたんだ。

幸い、特殊なGUI部品は使ってなかったので、我慢出来る時間内でインストールは完了した。 この点、Javaの世界は楽だよなあ。使う(使える)部品は限られているし、jdkを一発入れて おくだけで全ての用が済んでしまう。しかも、WindowsであろうとLinuxであろうとFreeBSDで あろうとソースは共通。ならば使わにゃ損ってもんだ。

先端を走るのは、JavaFXらしいけど、取り合えず基礎を抑えておかないとね。昔はawtだった ようだけど、今の主流はswingらしい。資料もいっぱい転がっているだろう。

Swingを使ってみよう とか てんぷらメモ とか とほほのJava入門 等、先生に紹介して貰った。後は自習ね。(オイオイ)

てんぷらメモには、Jrubyとのコラボも解説されてて面白そうなんだけど、おいらの主目的は clojureやってたらそのうちにswingにも行き当たるでしょ。その時に慌てふためかない為の 予習なんであります。

で、いきなり手ごろなアプリを試運転します。 ややこしい事にファイルが2本建てですよ。こういう場合、私の感では子分の方を先に コンパイルしておいて、それから親分の方を何するといいんだな。後、ソースに日本語が 混じってるようなので、コピペしたのを nkf -w して、UTF-8に統一しておくんだな。

[sakae@cdr ~/swing]$ javac RtfFilter.java
[sakae@cdr ~/swing]$ javac TextPaneTest.java
TextPaneTest.java:212: シンボルを見つけられません。
シンボル: 変数 omboFonts
場所    : TextPaneTest の クラス
        String fontName = omboFonts.getSelectedItem().toString();
                          ^
TextPaneTest.java:257: シンボルを見つけられません。
シンボル: クラス RtfFilter
場所    : TextPaneTest の クラス
    RtfFilter filter = new RtfFilter();
    ^
TextPaneTest.java:257: シンボルを見つけられません。
シンボル: クラス RtfFilter
場所    : TextPaneTest の クラス
    RtfFilter filter = new RtfFilter();
                           ^
エラー 3 個

何故エラーになるの? 最初にコンパイルしたやつが見つけられないのかな?こういう時は、 javac -help して、関係ありそうなオプションを探ってみます。そして、実験。

[sakae@cdr ~/swing]$ javac -cp . TextPaneTest.java
TextPaneTest.java:212: シンボルを見つけられません。
シンボル: 変数 omboFonts
場所    : TextPaneTest の クラス
        String fontName = omboFonts.getSelectedItem().toString();
                          ^
エラー 1 個

エラーが2つ消えてくれた。残る1個は難だろう? ひょっとして、今使ってるFreeBSDの Diablo Java じゃ、サポートしてないのだろうか?

そなら、FreeBSDにもopenjdkがportsになってるようなので、そちらで試してみるかな。 という事で、97Mのソースを御取りよせ、コンパイルしましたよ。

インストールしたけど、どうやって今のjava系と切り替えるの? 先生に聞いてみたけど そんなの知らん。自分で調べろと言われた。

[sakae@cdr ~/swing]$ which javac
/usr/local/bin/javac
[sakae@cdr ~/swing]$ ls -l /usr/local/bin/javac
lrwxr-xr-x  1 root  wheel  21  1  5 16:51 /usr/local/bin/javac@ -> /usr/local/bin/javavm
[sakae@cdr ~/swing]$ file /usr/local/bin/javavm
/usr/local/bin/javavm: POSIX shell script text executable

man javavm するもなく、こやつがJava系の切り替え器みたい。よって分解してみて原理が 分かったよ。

[sakae@cdr ~/swing]$ java -version
java version "1.6.0_07"
Diablo Java(TM) SE Runtime Environment (build 1.6.0_07-b02)
Diablo Java HotSpot(TM) Client VM (build 10.0-b23, mixed mode, sharing)
[sakae@cdr ~/swing]$ export JAVA_VENDOR=openjdk
[sakae@cdr ~/swing]$ java -version
openjdk version "1.7.0"
OpenJDK Runtime Environment (build 1.7.0-root_2010_04_29_08_46-b00)
OpenJDK Client VM (build 17.0-b10, mixed mode)
[sakae@cdr ~/swing]$ javac -version
javac 1.7.0

今回は、環境変数 JAVA_VENDORで切り替えたけど、他の環境変数名でも切り替えられる ようだ。

で、新しいJAVA系で再コンパイルしてみたけど、やはり同じエラーでしたよ。こりゃ もう、ソースに当たる鹿。エラーが出てる行の付近を見渡してみたら、変数名が化けて いる事が判明した。きっと nkfの変換の時にミスったのだろう。そういう事に しておこう。

早速実行したら、ちゃんと動きました、と言いたい所だけど、編集が出来なかった。 openjdk7って言うけど、java 1.7相当なのね。これって、SUNの得意技だったような。。。 確か、Solaris 2.8になった頃、2を省略して、どうだSolaris8だぞうって貫禄を 振りまいていたなあ。

そう言えば、出る出ると言われてさっぱり出てこないPerl6. いいかげんに諦めて、Perl5.12だかの5を省いて、堂々と、Perl12を名乗るがよろし。 なーに、SUNで前歴がありますし、誰も文句を言わんでしょう。そして、いつの間にか、 みんながPerl6なんてのが計画されてた事をすっかりと忘れてくれるので、ご安泰でっせ。

嗚呼、余計な事を書いてしまったわい。話を元に戻そう。openjdk7なんて、時期が早すぎ たね。 Java系をDiablo Javaに戻しちゃうと、日本語 表示が豆腐文字になってしまうんだけど、こちらを何とかした方が良さそう。

[sakae@cdr /usr/local/diablo-jdk1.6.0/jre/lib/fonts]$ sudo ln -s /usr/local/lib/X11/fonts/TTF fallback

調べて上記のようにしたら、ちゃんと日本語を表示したし、問題だった編集も動いた。 日本語入力もバッチリ(って、死語ですね)

Swing on Windows 7

調子に乗って、Windows 7でも、Swingしてみる。早くJDKを取ってきておかないと、目ざとい ボラクルの事、使うには金払えと言い出しかねませんから。

取りに行ったら、登録せんとダウンロードさせませんだと。昔からそうだったっけ?適当に 登録して取ってきた。脆弱な所が見つかってVer.が上がっていたよ。

ついでにJava界のmakeである、antとmaven2も入れておく。(車輪の再発明も甚だしいけど、 しぶしぶと流儀に従う)

FreeBSDで動いてたソースを持ってきてコンパイルしてみると、見事にエラーですよ。

c:\homes\tmp>javac -cp . TextPaneTest.java
TextPaneTest.java:19: 警告:この文字は、エンコーディング MS932 にマップできません。
  protected JComboBox comboFonts;  /* Font驕ク謚?*/
    :
TextPaneTest.java:310: ';' がありません。
  public void caretUpdate(CaretEvent e){
                                      ^
TextPaneTest.java:345: 構文解析中にファイルの終わりに移りました
}
 ^
エラー 22 個
警告 44 個

どうも、文字コードにSHIFTJISを期待してるっぽいぞ。よう分からんから、classファイルを 先に持ってきて実行してみると、

c:\homes\tmp>java -cp . TextPaneTest
Exception in thread "main" java.lang.UnsupportedClassVersionError: TextPaneTest
: Unsupported major.minor version 51.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(Unknown Source)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$000(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: TextPaneTest.  Program will exit.

ははは、どこでも動くなんてのは嘘じゃん。誇大広告でJAROに訴えてやる。

まあまて、この classファイルは、openjdk7なんていう、まだ市場には出回っていないもので作ったやつだ。 ちとコンパイラーのバージョンを戻してからコンパイルしてみるか。

うごいた。早走りは罪かなあ。でも、こんな事があっちゃ、安心して使えないよね。 バージョンが変わる度に動かなくなる某MSを目指してるんですかい? それとも、SUNが 無くなって、縛りが解けたので、好き放題やってますってか?

で、問題のソースの文字コードだけど、nkf -s して、SHIFTJISにしたやつを喰わせて みたらエラーもなくコンパイル出来た。ボラクルの連中、$MSにおべっか使いおって、まったくもう!

javac -helpしてみると

  -encoding <encoding>       ソースファイルが使用する文字エンコーディングを指定する

こんなオプションが用意されてたよ。だったら時代に逆行するような挙動をデフォにするなよ。 あーあ、Java界も混沌としてきたなあ。

それから再びFreeBSDに戻るけど、1.6の環境でコンパイルしたクラスファイルは、openjdk7の 環境でロードは出来たよ。但し、編集出来ないって問題はあるけどね。

Swing on ArchLinux

こちらも試してみる。そしたら、やはり文字化け。解消の方法は、FreeBSDのそれと一緒 だろうと当たりを付けて

[sakae@arch ~]$ cd /opt/java/jre/lib/fonts
[sakae@arch fonts]$ sudo ln -s /usr/share/fonts/TTF fallback

これでOKになりました。それにしても、fontsが何処にあるか探すのに時間がかかるとは、 これいかに? java一族も変な所に入っているし。(ああ、/optってのは、Solaris流と 喝破出来なかったおいらは、まだ青二才だなあ)

[sakae@arch tmp]$ java -version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode)
[sakae@arch tmp]$ javac -version
javac 1.6.0_20

入ってるJAVA系は、SUN純正のやつ。こやつで、SJISのソースをコンパイルしたら、 文句垂れるよなあ。

TextPaneTest.java:106: warning: unmappable character for encoding ASCII
    sb.append("?X?^?C???????????\?????????????B");
                          ^
TextPaneTest.java:106: warning: unmappable character for encoding ASCII
    sb.append("?X?^?C???????????\?????????????B");
                           ^
TextPaneTest.java:106: illegal escape character
    sb.append("?X?^?C???????????\?????????????B");
                                 ^
1 error
100 warnings

UTFかと思ったら、ASCII期待ね。やっぱり、UTFなんてやつらは嫌いなんだな。こういう所 で本心が伺えて面白い。まるで、英国の首相みたいだな。

[sakae@arch tmp]$ javac -encoding ms932 -cp . TextPaneTest.java
[sakae@arch tmp]$

そなら、日本人に取って今や標準の文字エンコードとなりつつある、UTF-8にしてから コンパイルしてみよう。

[sakae@arch u]$ nkf -g TextPaneTest.java
UTF-8
[sakae@arch u]$ javac -cp . TextPaneTest.java
  :
TextPaneTest.java:69: warning: unmappable character for encoding ASCII
    /* ??????????????????????????? */
             ^
100 warnings

かろうじて、クラスファイルは出来上がったけど、実行すると文字が化け化け。

[sakae@arch u]$ javac -encoding utf8 RtfFilter.java
[sakae@arch u]$ javac -encoding utf8 -cp . TextPaneTest.java
[sakae@arch u]$

今度は大丈夫でしたよ。やれやれ、難儀な事だわい。でも、可笑しいよなあ。 天下のSUNがASCII決め打ちだなんて。考えられるのは、localeか。

[sakae@arch u]$ echo $LANG
en_US.utf8

ピンポン。アメリカ仕様だったわい。疑ってごめん。

[sakae@arch u]$ locale -a
C
POSIX

ありゃ? 英語しかないよ。こういう時は /etcの下を覗くに限る。そして怪しそうな 名前のファイルを発見。locale.gen って、らしい名前だよね。開いてみて、jaの所の コメントを外してあげて、locale-gen なんて言う、多分1回しか使わんコマンドを 叩く。そしたら、ja_JP.utf8 が見えてきた。

後はこやつを /etc/rc.confに設定して再起動。これで、無事に日本仕様になりました。 javacも、-encodeing 無しで、無事にコンパイル出来るようになりましたとさ。

I love FX

ついでなので、javaFXでもやってみるか。これなら、財産を巻き上げられる事もなかろう から良いよね。

早速、SunもとえOracleのサイトへ取りに行ってきた。対応OSにFreeBSDが無いとは、どう いう事よ。しかも、Linuxもウブンツだけがリストアップされてるし。。 もう、いじけて、BSD MAGAZINEでも読んでいようかな。

取り合えず落としてきて、ArchLinuxで試してみると

[sakae@arch fx]$ sh javafx_sdk-1_3-linux-i586.sh
javafx_sdk-1_3-linux-i586.sh: line 11: [: 1685116: unary operator expected
Unpacking...
Checksumming...
1
The download file appears to be corrupted.  Please refer
to the Troubleshooting section of the Installation
Instructions on the download page for more information.
Please do not attempt to install this archive file.

なんてこったい。だめじゃん。DLに失敗でもしてるんかと、再度DLして試すも同じ結果。 ちょっと癪に障るので、FreeBSDからDLしてみた。そして、自嘲ぎみにDLしたファイルを editorで開いてみたよ。

ファイルの頭の方にshell語で書かれたインソトーラがあって、後ろの方に圧縮された javaFXがあるようだ。インストーラを解読してみると、土台はLinuxさんですね。Diskに 空き容量はありますね。そんじゃ、圧縮部分を取り出します。一応sumを取って、壊れて いないか確認します。OKだったら、自己解凍します。bin/以下の数個のファイルに 実行属性を付けます。いらなくなったファイルを削除します。多分、自己解凍の部分は Javaの大好物zipになってると予想。

FreeBSDでやるには、自己解凍の部分が走るかが問題になりそうだけど、ひょっとしてzip だったりしませんか? unzip使えないかな? いたずらしてみる。 その前に肝は、インストーラ中にある

tail ${tail_args}+64 $0 > $outname
  :
    if expr $sum1 != 29343 || expr $sum2 != 47841  ; then

tailの引数に、プラスの数字を与えた場合の挙動。余のtailにそんな機能は無いので 手動で前半部分を削除。

[sakae@cdr ~/fx]$ sum javafx_sdk-1_3-linux-i586.sh
47449 47841 javafx_sdk-1_3-linux-i586.sh
[sakae@cdr ~/fx]$ file javafx_sdk-1_3-linux-i586.sh
javafx_sdk-1_3-linux-i586.sh: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, stripped

sumが合わないなあとつぶやきつつ unzip するとエラーも無く展開出来ちゃいました。 おまけに

[sakae@cdr ~/javafx-sdk1.3/bin]$ ./javafx -version
javafx 1.3.0_b412
[sakae@cdr ~/javafx-sdk1.3/bin]$ ./javafxc -version
javafxc 1.3.0_b412

どうやら動いてるっぽい。本当かなあ? 何か作って動かしてみる。

[sakae@cdr ~/fx]$ javafxc love.fx
[sakae@cdr ~/fx]$ javafx -cp . love
Exception in thread "AWT-EventQueue-0" java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
        at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:159)

あらら、println('I love FX'); こんなのにも、X環境が必要なんかいな! ちゃんとX環境の上で動かしてみたら、FXするならご自身の責任でと言う書類にサイン させられたよ。それが済めば、普通の文字端末でも、問題なく動いたよ。

どこまで動くか Java in the BOXで確認したら、結構動いた象。 気をよくして、付いてきたサンプルを試そうと思ったら、みんなWeb上で動かす事を 念頭に置いたものばかりで、ちと残念でした。 おまけに、libの中には、linuxの根性を叩き込まれている so ファイルが有ったりして FreeBSDは、やっぱり蚊帳の外でしたね。

結局javaFXって、Web屋さんの道具みたいだな。今頃初めてもアドビのフラッシュに 勝てるんか? まあ、アドビは世界を席巻しちゃって、あぐらをかいてるからなあ。 核弾頭に竹槍じゃ勝負にならんよ。そうそう、オバマに命令して、核弾頭は解体する ようにさせればいいんか。そして、世界的に使用禁止にすると。。。

でもタイミング良く、FXの文法 なんてのも公開されたみたいだし、一から勉強してみる?