昨日の夜あたりから、JavaSwingで、空白文字を可視化するテキストフィールドの作成に挑戦していました。
参考にしたのは、以下のaterai氏のサイトの「JTextPaneで全角スペースやタブを可視化」というサンプル。
http://terai.xrea.jp/Swing.html
途中の御託はいいからどんなのか見せろよ!という方は、最後の方を見てください。
ここからは、ちょっと説明を含めていろいろ書きます。
初めは、JEditorPaneをJTextFieldみたいに1行表示にしようと思いましたが、あえなく断念。
PlainDocument.insertString()をパクって改行を無視させたり色々やってみましたが、
・UIがJTextFieldみたいにならない。やることが多すぎてめんどー。
・キーアクションの設定がめんどー。
と、いろいろあってやめました。
そのあと、BasicTextFieldUIで、aterai氏のサンプルのEditorKitを読み込ませる方法に変更。
素直にこっちやっていればよかった・・・。
やることは簡単。
BasicTextFieldUI.getEditorKit()をオーバーライドして、aterai氏のサンプルのMyEditorKitを返すようにするだけ。
おお、簡単簡単。
ただ、UIって、MetalとかWindowsとかMotifとかいろいろあるので、JTextFieldのサブクラスを作って、
UIがMetalTextFieldUIなら、それのサブクラスを設定して、とちょっとひねってみてます。
ただ、aterai氏の
WhitespaceLabelViewでは可視化したものが変な位置に表示されてしまいました。
テキストフィールド内に文字列が収まれば問題ないのですが、テキストフィールドの幅より長い文字列が入ると、
可視化のために表示した図形がスクロール前のところに表示されたままになる、という問題です。
サンプルは、JTextPane用の物なので、JTextFieldのようにスクロールペインなしでスクロールすることを考慮していないのが原因と思われます。(詳しくないので正確なことはわかりません)
そこで、同サイトにあった「JEditorPaneで改行を表示」というサンプルを見てみると、modelToView()というスクロール(っぽいの)に対応したコードがあるじゃないですか!
で、さっそくこれをパ・・・、もとい参考にして組み直してみました。
が、今度は図形が行末に表示されるようになりました・・・。
よくよく見ると、modelToView()の第1引数がgetEndOffset()になっていました。
これは、表示する範囲の最後を意味するらしく、そこからスクロール後の座標を計算していたために行末になってたっぽいです。
直し方は、getStartOffset()で行の先頭から座標を計算するようにするだけ。
色々書きましたが、ほとんどがサンプルソースをそのままで、自分で新しいことは特にやってません。
これだけだとあんまりなので、ちょっと汎用性を持たせるために、外部から置き換える文字と変わりに表示する図形を紐づけられるようにしてみました。
以下にサンプロプログラムとソース、実行結果のスクリーンショットを置きます。
ちなみに、サンプルプログラムではWordみたいに、
・半角スペースは小さい中点にする
・タブは小さい→にする
・全角スペースは□にする
ようになってます。
ただ、なぜかタブはうまくいかないことがある・・・。JTextFieldでもなんかうまくいかないんだけど、何故だろう??
↑スクリーンショットです。
WSVTextField_src.zip
↑サンプルプログラムのソースです。
WSVTextField_doc.zip
↑JavaDocです。
WSVTextField.jar
↑サンプルプログラムのJarです。Java1.6を想定しています。
で、いつものごとく免責事項を。
この記事で紹介したサンプルソースやプログラムを使用して起こったいかなる不具合、不都合などについて、私マインは一切の責任を負いません。
全て自己責任で使用してください。
また、ソース中やJavaDocに記載している内容に誤りがあっても責任を負いませんし、説明もしません。
それから、もしここのソースを使う場合は、aterai氏に感謝しましょう。
それと、勝手に紹介してすみません・・・m(_ _)m
それにしても、久しぶりのまともっぽいブログだった。
さて、スパロボUXを始めますか。
[0回]
PR
John
2014/04/25(Fri)01:32
No.1|by Smithk561|URL|Mail|Edit