PR

 今回もJava SE 7に導入予定の技術を紹介します。といっても、前回のProject Lambdaのように実装がないものではなく、既に存在している技術です。

 読者の皆さんはSwingXというプロジェクトをご存じでしょうか?

 標準ではSwingに含まれないコンポーネントなどを開発しているプロジェクトです。例えば、JTableやJListを拡張したJXTableやJXListなどがSwingXに含まれています。

 残念ながら、SwingXは一昨年Sun Microsystemsからの支援が打ち切られてしまい、風前の灯火となっています。

 そんなSwingXの中で、唯一Java SE 7に採用されることが決まったのが、今回取りあげるJXLayerです。

 JXLayerは通常のSwingコンポーネントと異なり、単体で使用するコンポーネントではありません。ほかのコンポーネントと組み合わせて、そのコンポーネントを装飾させるためのコンポーネントです。

 そういう意味ではJXLayerはJScrollPaneクラスに似た部分があります。

 JScrollPaneクラスは単体で使用することはありません。ほかのコンポーネントと組み合わせ、そのコンポーネントをスクロールバーで装飾するために用います。

 JScrolPaneクラスはスクロールバーに特化していますが、JXLayerは汎用に使用できる装飾のためのコンポーネントなのです。

JXLayerに至った背景

 JXLayerを紹介する前に、なぜJXLayerが必要になったのかを少し考えてみましょう。

 Javaで円や四角を描画するにはJava 2Dを使用します。Java 2Dには様々な機能があります。ベジェ曲線で描画したり、イメージに様々なエフェクトをかけることもできます。

 では、Java 2DをSwingと一緒に使うにはどうしたらよいでしょうか?

 その答えはJava 2Dを使用した描画を行うコンポーネントを継承して、サブクラスを作成するという方法です。

 Swingのjavax.swing.JComponentクラスにはpaintComponentメソッドがあります。Java 2Dを使用するには、このメソッドをオーバーライドします。

 例えば、四角を描画するためには次のようなクラスを作成します。

public class Square extends JComponent {
    @Override
    protected void paintComponent(Graphics g) {
        g.setColor(Color.RED);
        g.fillRect(10, 10, 50, 50);
    }
}

 しかし、これでは描画する種類が変化する度に、新たなサブクラスを作成しなくてはなりません。

 Swingが設計されたのは10年以上前であり、継承がよく使用されていた時代です。しかし、現在では以前に比べると継承の重要性は減っています。

 その代わりに使われるようになったのが、コンポジションです。

 Swingでも、描画の機能をコンポジション化すれば、上記のようなサブクラスを作成する必要はありません。

 例えば、Painterというインタフェースを定義し、JComponentクラスにsetPainterメソッドを追加すれば、もっと柔軟に描画のためのコードを記述することができます。

 クラス図で書けば、現在の継承を使用した設計が図1、コンポジションを使用した設計が図2になります。

図1●継承を用いた設計
図1●継承を用いた設計
図2●コンポジションを用いた設計
図2●コンポジションを用いた設計
[画像のクリックで拡大表示]

 残念ながら、現在のSwingをコンポジションを利用した設計に変更するには、影響が大きすぎます。

 そこで登場したのがJXLayerです。

 JXLayerはコンポーネントを修飾するために、コンポジションを用いた設計になっています。

 JXLayerの基本となるのがJXLayerクラスです。JXLayerクラスは修飾する対象のコンポーネントを保持し、描画機能を委譲するためにLayerUIインタフェースを使用します。

 つまり、コンポーネントを修飾するための処理はLayerUIインタフェースを実装したクラスに記述します。

これをクラス図で表したのが図3です。

図3●JXLayerの設計
図3●JXLayerの設計
[画像のクリックで拡大表示]

 実際には、LayerUIに委譲するのは描画だけでなく、イベント処理などもあります。このため、LayerUIインタフェースを直接実装したクラスを作成するのではなく、LayerUIを実装したアブストラクトクラスのAbstractLayerUIクラスのサブクラスを使用するようにします。

 では、次章からJXLayerの使い方について紹介していきます。