SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Swing再入門

Swing再入門 コンポーネントの表示方法のカスタマイズ

第2回 コンポーネントの表示を考える

Metalを自由に変更できますか?

 ルックアンドフィールというのは基本的に主なOS用に用意されているものですが、その中でJava独自のものとして用意されているのが「Metal」です。非常にシンプルですが、独特の雰囲気を持ったルックアンドフィールです。

 このMetalは、他のルックアンドフィールにはない特徴があります。それは、ルックアンドフィールの表示(各コンポーネントの色やフォントなど)を簡単にカスタマイズすることができるという点です。Metalのためのルックアンドフィール・クラスを継承して独自にプロパティを定義することで、オリジナルな色合いのMetalルックアンドフィールを作れます。

 実際に、ごく簡単なMetalルックアンドフィール・クラスを作成してみましょう。「MyMetalTheme」というクラスを作成し、次のように定義してください。

package jp.codezine;

import java.awt.Color;

import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.metal.DefaultMetalTheme;

public class MyMetalTheme extends DefaultMetalTheme {
    private final String name;
    private final ColorUIResource primary1;
    private final ColorUIResource primary2;
    private final ColorUIResource primary3;
    private final ColorUIResource secondary1;
    private final ColorUIResource secondary2;
    private final ColorUIResource secondary3;
    private final ColorUIResource menuForeground;
    private final ColorUIResource menuBackground;
    private final ColorUIResource menuSelectedForeground;
    private final ColorUIResource menuSelectedBackground;
    
    public MyMetalTheme(){
        name = "MyMetal";
        primary1 = new ColorUIResource(new Color(150,100,100));
        primary2 = new ColorUIResource(new Color(200,100,100));
        primary3 = new ColorUIResource(new Color(255,200,200));
        secondary1 = new ColorUIResource(new Color(120,90,90));
        secondary2 = new ColorUIResource(new Color(150,120,120));
        secondary3 = new ColorUIResource(new Color(255,220,220));
        menuForeground = new ColorUIResource(new Color(255,150,150));
        menuBackground = new ColorUIResource(new Color(75,50,50));
        menuSelectedForeground =
            new ColorUIResource(new Color(50,0,0));
        menuSelectedBackground = 
            new ColorUIResource(new Color(200,160,160));
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    protected ColorUIResource getPrimary1() {
        return primary1;
    }
    @Override
    protected ColorUIResource getPrimary2() {
        return primary2;
    }
    @Override
    protected ColorUIResource getPrimary3() {
        return primary3;
    }

    @Override
    protected ColorUIResource getSecondary1() {
        return secondary1;
    }
    @Override
    protected ColorUIResource getSecondary2() {
        return secondary2;
    }
    @Override
    protected ColorUIResource getSecondary3() {
        return secondary3;
    }

    @Override
    public ColorUIResource getMenuBackground() {
        return menuBackground;
    }
    @Override
    public ColorUIResource getMenuForeground() {
        return menuForeground;
    }
    @Override
    public ColorUIResource getMenuSelectedBackground() {
        return menuSelectedBackground;
    }
    @Override
    public ColorUIResource getMenuSelectedForeground() {
        return menuSelectedForeground;
    }
}

Metalのテーマの仕組み

 Metalルックアンドフィールは、javax.swing.plaf.metal.MetalTheme抽象クラスを継承した「DefaultMetalTheme」というクラスを「テーマ」として設定し表示します。テーマというのは、各コンポーネントの色やフォントなどのセットのことです。このテーマを新たに定義し、Metalルックアンドフィールに設定することで、Metalの表示色などをカスタマイズできるのです。

 DefaultMetalThemeには、以下の6つのメソッドが用意されています。これらで返すColorUIResourceによって、コンポーネント類の表示色が決められます。

protected ColorUIResource getPrimary1();
protected ColorUIResource getPrimary2();
protected ColorUIResource getPrimary3();
protected ColorUIResource getSecondary1();
protected ColorUIResource getSecondary2();
protected ColorUIResource getSecondary3();

 返値のColorUIResourceは、引数にColorを渡してnewし作成します。これにより、引数に指定した色のColorUIResourceが用意できます。これらのメソッドを用意するだけですから、クラスの作成は非常に単純です。

 ただし、これだけでは細かな表示が行えません。特に重要なのは、メニュー関係でしょう。このままだと、コンポーネントもメニューもすべて同じ色合いになってしまいます。そこで、ここではDefaultMetalThemeのスーパークラスであるMetalThemeのメニュー関係のメソッドをオーバーライドして、メニューの色を独自に定義しています。

public ColorUIResource getMenuForeground();
public ColorUIResource getMenuBackground();
public ColorUIResource getMenuSelectedForeground();
public ColorUIResource getMenuSelectedBackground();

 これらを用意することで、メニューの通常状態と選択状態の前景色・背景色をそれぞれ設定できます。この他にもMetalThemeにはフォント関係などいくつものメソッドが用意されています。

MyMetalThemeで表示する

 では、作成したMyMetalThemeをテーマに設定して、アプリケーションを表示させてみましょう。先ほどのSampleAppを修正して、独自のMetalルックアンドフィールでアプリケーションを表示させてみます。コンストラクタとcreateComponentを次のように修正します。

// import javax.swing.plaf.metal.*;

public SampleApp(){
    this.setSize(new Dimension(200,200));
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    GridLayout layout = new GridLayout(4,1);
    layout.setHgap(5);
    layout.setVgap(5);
    this.setLayout(layout);
    MetalLookAndFeel.setCurrentTheme(new MyMetalTheme());
    try {
        UIManager.setLookAndFeel(new MetalLookAndFeel());
        SwingUtilities.updateComponentTreeUI(this);
    } catch (UnsupportedLookAndFeelException e) {
        e.printStackTrace();
    }
    
    createComponent();
}

public void createComponent(){
    JMenuBar mbar = new JMenuBar();
    JMenu menu = new JMenu("File");
    menu.add(new JMenuItem("Test"));
    menu.add(new Separator());
    menu.add(new JMenuItem("Quit"));
    mbar.add(menu);
    this.setJMenuBar(mbar);
    JCheckBox check = new JCheckBox("checkbox");
    this.add(check);
    JRadioButton radio = new JRadioButton("radio");
    this.add(radio);
    combo = new LaFComboBox();
    combo.addActionListener(this);
    this.add(combo);
    JButton btn = new JButton("button");
    this.add(btn);
}
MyMetalThemeのテーマを使ってMetalルックアンドフィールを表示したところ。
MyMetalThemeのテーマを使ってMetalルックアンドフィールを表示したところ。

 テーマの設定は、MetalLookAndFeel.setCurrentThemeを呼び出して行います。ここで引数にテーマ・クラスのインスタンスを渡すだけです。その後、UIManager.setLookAndFeelを使ってルックアンドフィールを設定し、SwingUtilities.updateComponentTreeUIで更新を行っておきます。

 ここでは、setLookAndFeelの引数にLookAndFeelクラスを指定しています。この場合、発生する例外はUnsupportedLookAndFeelExceptionだけですので、Stringでクラス名を指定するよりもずいぶんcatch節がすっきりしますね。

まとめ

 今回は、ボーダーやルックアンドフィールといった、コンポーネントの表示関係についていくつかのテクニックを紹介しました。特にルックアンドフィールの変更などは、いかにもSwingらしい機能と言えるでしょう。こうした機能を使いこなせるようになると、Swingの柔軟さを実感できるはずです。

 基本的なコンポーネントだけでも、こうした機能を使いこなすことで思った以上に高度なレイアウトを作成していくことができます。コンポーネント活用と言うとすぐに「オリジナルコンポーネントの開発」に飛びついてしまう感じがありますが、まず基本的なコンポーネントを徹底的に使いこなすことから考えましょう。案外、それで済んでしまうことの方が多いのではないでしょうか。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
Swing再入門連載記事一覧

もっと読む

この記事の著者

掌田 津耶乃(ショウダ ツヤノ)

三文ライター&三流プログラマ。主にビギナーに向けたプログラミング関連の執筆を中心に活動している。※現在、入門ドキュメントサイト「libro」、カード型学習サイト「CARD.tuyano.com」を公開...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1640 2007/09/05 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー