• category: swing folder: FontChange title: UIManagerで使用するFontを統一 tags: [UIManager, Font] author: aterai pubdate: 2003-10-27 description: Swingの各種コンポーネントで使用する全てのフォントを一気に変更します。 image: https://lh4.googleusercontent.com/_9Z4BYR88imo/TQTNJ5XQrjI/AAAAAAAAAaU/lvxCohYLmBI/s800/FontChange.png

概要

概要

Swingの各種コンポーネントで使用する全てのフォントを一気に変更します。

サンプルコード

サンプルコード

private void updateFont(final Font font) {
  FontUIResource fontUIResource = new FontUIResource(font);
  for(java.util.Map.Entry<?,?> entry: UIManager.getDefaults().entrySet()) {
    if(entry.getKey().toString().toLowerCase().endsWith("font")) {
      UIManager.put(entry.getKey(), fontUIResource);
  // 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);
  });
  // SwingUtilities.updateComponentTreeUI(this);
  recursiveUpdateUI(this);
  frame.pack();
}
#spanadd

#spanend
private void recursiveUpdateUI(JComponent p) {
  for(Component c: p.getComponents()) {
    if(c instanceof JToolBar) {
  for (Component c: p.getComponents()) {
    if (c instanceof JToolBar) {
      continue;
    }else if(c instanceof JComponent) {
      JComponent jc = (JComponent)c;
    } else if (c instanceof JComponent) {
      JComponent jc = (JComponent) c;
      jc.updateUI();
      if(jc.getComponentCount()>0) recursiveUpdateUI(jc);
      if (jc.getComponentCount() > 0) {
        recursiveUpdateUI(jc);
      }
    }
  }
}
View in GitHub: Java, Kotlin

解説

解説

上記のサンプルでは、ツールバーのボタンでコンポーネントが使用するフォントを切り替えています。ただしツールバーだけは、UIupdate(フォントの変更)を除外しています。
全部のコンポーネントではなく、例えばテーブルのフォントだけ変更したい場合は以下のように設定します。
  • -
  • 全コンポーネントではなく、例えばJTableのフォントだけ変更したい場合はTable.fontをキーにして以下のように設定する
    UIManager.put("Table.font", new FontUIResource(font));
    
UIManagerから、UIDefaultsのキー一覧を作るなどして、いろいろ検索してみてください。
  • 各コンポーネントのキーは、UIManagerからUIDefaultsのキー一覧が作成可能
    #spandel
    //キー一覧の作成例
    #spanend
    #spandel
    import java.util.Map;
    #spanend
    #spanadd
    // キー一覧の作成例
    #spanend
    import javax.swing.UIManager;
    #spanadd
    
    #spanend
    class Test {
      public static void main(String[] args) {
        //for(Object o:UIManager.getDefaults().keySet()) //は、うまくいかない?
        //for(Object o:UIManager.getLookAndFeelDefaults().keySet())
        for(Map.Entry<?,?> entry: UIManager.getDefaults().entrySet())
          System.out.println(entry.getKey());
        UIManager.getLookAndFeelDefaults().forEach((key, value) -> System.out.println(key));
      }
    }
    

Metalで使用されているフォントが気に入らないだけなら、システムLookAndFeelを使用するか、Metalでボールドフォントを無効にするなどの方法があります。
  • MetalLookAndFeelではなく、SystemLookAndFeelを使用する
#spanend
#spandel
try{
#spanend
  UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
#spandel
}catch(Exception e) {
#spanend
  e.printStackTrace();
#spandel
}
#spanend
#spandel
UIManager.put("swing.boldMetal", Boolean.FALSE);

  • JComboBox#setFont(...)で使用するフォントのサイズを変更しても、JComboBox自体のサイズが更新されない
    • JCombobox doesn't get resized according to font size change
      combo.setFont(font);
      #spandel
      //以下回避方法
      #spanend
      #spandel
      combo.setPrototypeDisplayValue(null); //null:default?
      #spanend
      #spandel
      //or combo.firePropertyChange("prototypeDisplayValue",0,1); //0,1:dummy
      #spanend
      #spanadd
      // 以下回避方法
      #spanend
      #spanadd
      combo.setPrototypeDisplayValue(null); // null:default?
      #spanend
      #spanadd
      // or combo.firePropertyChange("prototypeDisplayValue", 0, 1);
      #spanend
      

特定のインスタンスだけ、LookAndFeelなどを変更しても常に独自のフォントを設定したい場合、JComponent#updateUI()をオーバーライドして設定する方法もあります。

JLabel label = new JLabel() {
  @Override public void updateUI() {
    super.updateUI();
    setFont(...);
  }
};

参考リンク

参考リンク

コメント

コメント