Look&Feelを設定する

広告

現在設定されているLook&Feelとは別のLook&Feelを設定する方法を確認します。UIManagerクラスで用意されている「setLookAndFeel」メソッドを使います。

public static void setLookAndFeel(LookAndFeel newLookAndFeel) throws UnsupportedLookAndFeelException

newLookAndFeel を現在の Look & Feel として設定します。現在の Look & Fee
が null 以外 である場合、その上で uninitialize が呼び出されます。
newLookAndFeel が null 以外 である場合、その上で initialize が呼び出され、
続いて getDefaults が呼び出されます。それまでの Look & Feel のデフォルト
は、newLookAndFeel.getDefaults() が返すデフォルトに置き換えられます。
newLookAndFeel が null の場合、Look & Feel のデフォルトは null に設定さ
れます。

値 null は、Look & Feel を null に設定する場合に使用できます。ほとんどの
場合、Swing を機能させるためには LookAndFeel が必要です。したがって、
LookAndFeel を null に設定することはまったくお勧めしません。

パラメータ:
  newLookAndFeel - インストールする LookAndFeel
例外:
  UnsupportedLookAndFeelException - newLookAndFeel が null 以外 で、
    newLookAndFeel.isSupportedLookAndFeel() が false を返す場合

引数に新しく設定したいLook&Feelを表すLookAndFeelクラスのオブジェクトを指定します。

また同じ名前のメソッドで引数が異なるものも用意されています。

public static void setLookAndFeel(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException

現在のスレッドのコンテキストクラスローダーを使って、指定のクラス名で示さ
れる LookAndFeel をロードし、setLookAndFeel(LookAndFeel) に渡します。

パラメータ:
  className - Look & Feel を実装するクラスの名前を指定する文字列 
例外: 
  ClassNotFoundException - LookAndFeel クラスが見つからなかった場合 
  InstantiationException - クラスの新しいインスタンスを生成できなかった
    場合
  IllegalAccessException - クラスまたは初期化子にアクセスできない場合 
  UnsupportedLookAndFeelException - lnf.isSupportedLookAndFeel() が
    false の場合 
  ClassCastException - LookAndFeel を拡張するクラスを、className で識別
    できない場合

引数に設定したいLook&Feelを表すLookAndFeelクラスのクラス名をString型の値として指定します。

Look&Feelを変更したらSwingアプリケーションで使われている各コンポーネントに更新を通知する必要があります。具体的にはボタンやラベルなどの各コンポーネントで「updateUI」メソッドを実行する必要がありますがSwingUtilitiesクラスで用意されている「updateComponentTreeUI」メソッドを使うとこの作業を簡略的に行うことが可能です。

public static void updateComponentTreeUI(Component c)

単純な Look & Feel の変更で、ツリー内の各ノードに updateUI() 処理を行う
こと、つまり現在の Look & Feel でその UI プロパティーを初期化することを
要求します。

引数にアプリケーションのトップとなるコンポーネントを指定すると、そのコンポーネントの配下にある各コンポーネントに対しても「updateUI」を実行してくれます。よって引数にアプリケーションの一番大元であるフレームを指定して実行することにより各コンポーネントに個別に「updateUI」を実行する必要がなくなります。

実際の使い方は次のようになります。

String lafClassName = "javax.swing.plaf.metal.MetalLookAndFeel";
try{
  UIManager.setLookAndFeel(lafClassName);
  SwingUtilities.updateComponentTreeUI(this);
}catch(Exception e){
  e.printStackTrace();
}

サンプルプログラム

では簡単なサンプルを作成して試してみます。

UIManagerTest3.java

import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.*;
import java.util.Vector;

public class UIManagerTest3 extends JFrame implements ActionListener{

  public static void main(String[] args){
    UIManagerTest3 frame = new UIManagerTest3();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setBounds(10, 10, 450, 300);
    frame.setTitle("タイトル");
    frame.setVisible(true);
  }

  UIManagerTest3(){

    JButton btn1 = new JButton("Metal");
    JButton btn2 = new JButton("CDE/Motif");
    JButton btn3 = new JButton("Windows");
    JButton btn4 = new JButton("WindowsClassic");

    btn1.addActionListener(this);
    btn1.setActionCommand("javax.swing.plaf.metal.MetalLookAndFeel");
    btn2.addActionListener(this);
    btn2.setActionCommand("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
    btn3.addActionListener(this);
    btn3.setActionCommand("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    btn4.addActionListener(this);
    btn4.setActionCommand("com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel");

    JPanel buttonPanel = new JPanel();
    buttonPanel.add(btn1);
    buttonPanel.add(btn2);
    buttonPanel.add(btn3);
    buttonPanel.add(btn4);

    String[] listData = {"Blue", "Green", "Red", "Whit", "Black", "Yellow"};
    JList list = new JList(listData);
    JScrollPane scrollPane1 = new JScrollPane();
    scrollPane1.getViewport().setView(list);
    scrollPane1.setPreferredSize(new Dimension(200, 80));

    JPanel listPanel = new JPanel();
    listPanel.add(scrollPane1);

    JCheckBox checkBox1 = new JCheckBox("JCheckBox1");
    JCheckBox checkBox2 = new JCheckBox("JCheckBox2", true);

    JPanel checkPanel = new JPanel();
    checkPanel.add(checkBox1);
    checkPanel.add(checkBox2);

    Vector<String> vector = new Vector<String>();
    for (int i = 0 ; i < 10 ; i++){
      StringBuffer sb = new StringBuffer();
      sb.append("JTree Node");
      sb.append(i);
      vector.add(new String(sb));
    }

    JTree tree = new JTree(vector);
    tree.setRootVisible(true);
    JScrollPane scrollPane2 = new JScrollPane();
    scrollPane2.getViewport().setView(tree);
    scrollPane2.setPreferredSize(new Dimension(200, 80));

    JPanel treePanel = new JPanel();
    treePanel.add(scrollPane2);

    JPanel p = new JPanel();
    p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
    p.add(listPanel);
    p.add(checkPanel);
    p.add(treePanel);

    getContentPane().add(p, BorderLayout.CENTER);
    getContentPane().add(buttonPanel, BorderLayout.PAGE_END);
  }

  public void actionPerformed(ActionEvent e){
    String lafClassName = e.getActionCommand();

    try{
      UIManager.setLookAndFeel(lafClassName);
      SwingUtilities.updateComponentTreeUI(this);
    }catch(Exception ex){
      System.out.println("Error L&F Setting");
    }
  }
}

上記をコンパイルした後で実行すると次のように表示されます。

UIManagerでLookAndFeelを切り替える

デフォルトのLookAndFeelである「Metal」で表示されています。画面下部のボタンをクリックすることでLookAndFeelを切り替えることができます。

Motif:

UIManagerでLookAndFeelを切り替える

Windows:

UIManagerでLookAndFeelを切り替える

WindowsClassic:

UIManagerでLookAndFeelを切り替える

LookAndFeelを変更してもフレーム自身の外観は変更されていません。フレームの外観についても変更する方法は次のページで確認します。

( Written by Tatsuo Ikura )

プロフィール画像

著者 / TATSUO IKURA

これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。