Swing/FontChange のバックアップの現在との差分(No.3)
TITLE:UIManagerで使用するFontを統一
UIManagerで使用するFontを統一
編集者:Terai Atsuhiro~
作成日:2003-10-01
更新日:2024-02-15 (木) 20:22:19
概要
Swing
の各種コンポーネントで使用する全てのフォントを一気に変更します。
Screenshot
Advertisement
概要
Swingの各種コンポーネントで使用する全てのフォントを一気に変更します。 JavaHouse-Brewers:49474 Re: setFont に関してから引用しています。サンプルコード
#spanend
#spanadd
private void updateFont(final Font font) {
#spanend
FontUIResource fontUIResource = new FontUIResource(font);
// for (Map.Entry<?, ?> entry: UIManager.getDefaults().entrySet()) {
UIManager.getLookAndFeelDefaults().forEach((key, value) -> {
if (key.toString().toLowerCase(Locale.ENGLISH).endsWith("font")) {
UIManager.put(key, fontResource);
}
});
// SwingUtilities.updateComponentTreeUI(this);
recursiveUpdateUI(this);
frame.pack();
#spanadd
}
#spanend
#spandel
#screenshot
#spanend
#spanadd
private void recursiveUpdateUI(JComponent p) {
#spanend
for (Component c: p.getComponents()) {
if (c instanceof JToolBar) {
continue;
} else if (c instanceof JComponent) {
JComponent jc = (JComponent) c;
jc.updateUI();
if (jc.getComponentCount() > 0) {
recursiveUpdateUI(jc);
}
}
}
#spanadd
}
#spanend
#spanadd
View in GitHub: Java, Kotlinサンプルコード
Font font = new Font("Sans-serif", Font.TRUETYPE_FONT, 12); FontUIResource fontUIResource = new FontUIResource(font); UIDefaults defaultTable = UIManager.getLookAndFeelDefaults(); Set set = defaultTable.keySet(); Iterator it = set.iterator(); while(it.hasNext()) { Object o = it.next(); if(o instanceof String) { String s = (String)o; if(s.endsWith("font") || s.endsWith("Font")) { UIManager.put(s, fontUIResource); } } }
解説
上記のサンプルでは、ツールバーのボタンでコンポーネントが使用するフォントを切り替えています。ただしツールバーだけは、UI
のupdate
(フォントの変更)を除外しています。
- &jnlp;
- &jar;
- &zip;
- -
- 全コンポーネントではなく、例えば
JTable
のフォントだけ変更したい場合はTable.font
をキーにして以下のように設定する#spanend #spanadd UIManager.put("Table.font", new FontUIResource(font)); #spanend #spanadd
解説
上記のサンプルでは、ツールバーのボタンでコンポーネントが使用するフォントを切り替えています。ただしツールバーだけは、フォントの変更を除外しています。- 各コンポーネントのキーは、
UIManager
からUIDefaults
のキー一覧が作成可能#spanend #spanadd // キー一覧の作成例 #spanend #spanadd import javax.swing.UIManager; #spanend #spandel 全部のコンポーネントではなく、例えばテーブルのフォントだけ変更したい場合は以下のように設定します。 #spanend UIManager.put("Table.font", new FontUIResource(font)); #spanadd class Test { #spanend public static void main(String[] args) { UIManager.getLookAndFeelDefaults().forEach((key, value) -> System.out.println(key)); } #spanadd } #spanend #spanadd
//キー一覧の作成例 Set set = UIManager.getLookAndFeelDefaults().keySet(); Iterator it = set.iterator(); while(it.hasNext()) { System.out.println(it.next()); }
- -
-
MetalLookAndFeel
で使用されているボールドフォントは、以下のように変更可能- MetalLookAndFeelで太字フォントを使用しない
#spanend #spanadd UIManager.put("swing.boldMetal", Boolean.FALSE); #spanend #spanadd
- MetalLookAndFeelで太字フォントを使用しない
- Developing Accessible JFC Applications
- 自分だけのカッコ良いアプリを作りたい,の巻
- -
-
JComboBox#setFont(...)
で使用するフォントのサイズを変更しても、JComboBox
自体のサイズが更新されない- JCombobox doesn't get resized according to font size change
#spanend #spanadd combo.setFont(font); #spanend #spanadd // 以下回避方法 #spanend #spanadd combo.setPrototypeDisplayValue(null); // null:default? #spanend #spanadd // or combo.firePropertyChange("prototypeDisplayValue", 0, 1); #spanend #spanadd
- JCombobox doesn't get resized according to font size change
try{ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); }catch(Exception e) { //throw new InternalError(e.toString()); }
参考リンク
- Re: setFont に関して
- -
特定のインスタンスだけ、
LookAndFeel
などを変更しても常に独自のフォントを設定したい場合、JComponent#updateUI()
をオーバーライドして設定する方法もあります。
- -
特定のインスタンスだけ、
コメント
- JFileChooser インスタンス化前に上記ソースを実行すると ConcurrentModificationException がスローされるのですが... 「JDK1.4.2_02」プロパティーが動的に変化するとしたらあまり有効な方法でないのでは? -- MT?
- 割と手軽なので重宝するのですが、ちゃんとスレッド処理考えたほうがいいのかもしれませんね。 -- terai
- レスありがとうございます _ _)m とりあえず Container を辿りながら含まれている Component 毎に setFont 呼ぶようなユーティリティ用意してしのいでいます^^; -- MT?
- UIManagerのリストにないコンポーネント(独自で作成したボタンなどのコンポーネント)なども追加すると変更が適用されるのでしょうか? -- mari?
- JBottunなどのSwingコンポーネントを継承していれば変更されるはずです。 -- terai
- レスありがとうございます。その場合、独自のコンポーネントを追加すると、そのコンポーネントのみ変更が適用されますか?Panelを追加したら全てのpanelに適用されてしまってうまくいきませんでした。良い方法があったら教えてください。 -- mari?
- すべてのコンポーネントに一々設定するのが面倒な場合のための方法なので、上記の場合は使用する意味が無いですね(^^;。ある独自コンポーネントのみフォントを変えたいのなら、コンストラクタなどで普通にsetFontすればいいのでないかと思うのですが、どうなんでしょう?そうじゃなくて、あるパネル以下のコンポーネントのフォントを一気に変えたいということなんでしょうか? -- terai
- たびたびすみません。全体のフォントの大きさをツールバーの選択によって変化させるようにしたいです。フォントだけ変化させたいのですが、コンストラクタなどで勝手にsetBackgroundしているコンポーネントはLook and Feelで設定しているデフォルトのbackgroundに変わってしまいました。またnewするわけではないので、そのコンポーネントのみののデフォルトをどこかで設定できたらいいなー、と思いました。Look and Feelでもpanelだったらpanel全ての設定しかできないのでしょうか?有効な方法があったら教えてください。よろしくお願いいたします。 -- mari?
- Look and Feelで変更するのではなく、イベントリスナーを作って実装するのはどうでしょう?はずしてるかもしれませんが、とりあえずサンプル置いておきます。初期値はコンストラクタで指定してます。ツールバーじゃなくてメニューで、フォントを切り替えてます。コンボボックスを切り替えたときにサイズがおかしいのは愛嬌ということで…。 -- terai
- すばらしいサンプルありがとうございます!参考にさせていただきました☆フォントの変更をLook and Feelで行って、残りの描画できなかった背景色などをPropertyChangeListenerを実装して描画しなおす、という方法も考えたのですが、こちらでも問題ないでしょうか?主題から外れてしまって申し訳ありません・・・。 -- mari?
- 次のネタ用にイベント作っただけなので、PropertyChangeListener使うのはまったく問題ないと思います。むしろちゃんとJavaBeansにしてPropertyChangeListener使うほうがいいかもしれません(^^;。 -- terai
#spanend #spanadd JLabel label = new JLabel() { #spanend @Override public void updateUI() { super.updateUI(); setFont(...); } #spanadd }; #spanend #spanadd