今日の役に立たない一言 - Today’s Trifle! -

古い記事ではさまざまなテーマを書いていますが、2007年以降はプログラミング関連の話がほとんどです。

いろんなコンポーネントのデフォルト色を任意の色に設定する方法

いま、Twitterクライアントを自作してる。タイムラインとかMentionsとかをJTabbedPaneのタブで切り替えるようにしてあるんだけど、setBackground()で非選択状態のタブの背景色は変わるんだけど、選択状態のタブの色が変わらない。
ぐぐってみると、L&Fがメタルの場合は、javax.swing.plaf.metal.MetalTabbedPaneUIを拡張したクラスを作ってpaintTabBackground()メソッドをオーバーライドすればいいとかいう情報を発見。
JTabbedPane のタブ背景色設定 - YHR’s notes
いちお試してみたけど、背景色は変わっても、それ以外のタブの枠とかの色が元のままで、さらに不自然な感じになってもたー。
そこで、javax.swing.plaf.metal.MetalTabbedPaneUIやjavax.swing.plaf.basic.BasicTabbedPaneUIのソースを眺めてみたところ、インスタンスを生成するときに TabbedPane.hogehoge とかいう感じのキーで javax.swing.UIManager から getColor() メソッドでそれぞれの部分をペイントするための色を取得してるらしいってことがわかった。
つまり、JTabbedPane のインスタンスを生成する前に、UIManager#put(key, value)でお好みの色を設定しとけば、わざわざjavax.swing.plafのクラスを拡張しなくてもいいってことらしい。さっそく試してみたら期待通りに動作してくれた。それぞれの色を設定するためのキーはそれぞれのソース(javax.swing.plaf.なんちゃら)を読めば分かる。
これって、JTabbedPaneだけじゃなくて、他のコンポーネントでも同じように実装されてるみたいだから、全部のコンポーネントにいちいち setBackground()とかしなくても色を設定できちゃって、体力的にもかなりお得な感じ。
そんなら、前もってUIManagerに格納されてるキーの一覧を取得しとけば、便利かもって思ったわけだ。そこで

    UIDefaults defaults = UIManager.getDefaults();
    Set keys = defaults.keySet();
    for (Object o : keys) {
         System.out.println(o + "=" + defaults.get(o));
    }

とかしてみた。そしたら、4個しか要素がない。なんでやねん!て思って、UIDefaults のソースを見たら、内部的には Locale ごとに別々の Map で管理されてて、キーの一覧を取得できない構造になってた。。。
がっかり。