今週も先週に引き続いて,Synth Look&Feelについて解説していきます。

先週はイメージを使用してボーダーや背景を描画しました。しかし,イメージを使用すると,イメージの拡大・縮小が避けられません。そのため,イメージの劣化が起きてしまいます。

そこで,今週はイメージを使用しないでボーダーや背景を描画する方法を紹介します。ここまではXMLドキュメントとイメージだけで描画を行ってきましたが,イメージを使用しない場合Javaのコードが必要になります。

SynthPainterクラスを使用したボーダー,背景の描画

イメージを使用してボーダーや背景を描画する場合,XMLドキュメントには<imagePainter>要素を使用することは先週紹介しました。<imagePainter>要素では描画する領域に応じて,method属性で指定します。このmethod属性に対応するのが,javax.swing.plaf.synth.SynthPainterクラスのメソッドです。

実際にはイメージを使用する場合,SynthPainterクラスのサブクラスであるImagePainterクラスが使用され,イメージの読み込み,拡大・縮小をしています。

イメージを使わない場合でも,同じようなスキームで行うことができます。つまり,SynthPainterクラスのサブクラスを作成し,XMLドキュメントでこのクラスを使用するように指定します。

では,まず全体の背景部分を,この方法で描画してみましょう。使用するサンプルは先週と同じです。

サンプルのソース (こちらからダウンロードできます)
・SynthSample.java
・RootPanePainter.java
・TextFieldPainter.java
・ButtonPainter.java

はじめにXMLドキュメントを書いてしまいましょう。該当部分を以下に示します。ここに示した以外の部分は先週のXMLドキュメントと同じです。

  <object id ="rootPanePainter" class="RootPanePainter" />
        
  <style id="rootpane">
    <painter method="rootPaneBackground" idref="rootPanePainter" />
  </style>
  <bind style="rootpane" type="region" key="RootPane" />

SynthPainterクラスのサブクラスを記述するのが,赤字で示した<object>要素です。

<object>要素は二つの属性を持ちます。一方がid属性,もう一方がclass属性です。class属性にはSynthPainterクラスのサブクラスの名前をパッケージも含めて記述します。ここでは,パッケージのないデフォルトパッケージを使用したので,RootPanePainterというクラス名だけになっています。

id属性はclass属性で示したクラスのIDになります。ここではroooPanePainterという値にしました。なお,<style>要素でもid属性を使用していますが,それぞれのIDは独立ではないので同じIDにならないようにしましょう。

そして,実際に描画を指定するのが,青字で示した<painter>要素です。

<painter>要素は<imagePainter>要素と同様に,method属性でどこの領域を描画するかを指定します。ここでは,ルートペインの背景を描画するので,rootPaneBackgroundにしました。

そして,実際に描画するクラスはidref属性により,IDで指定します。ここでは,rootPanePainterを指定し,RootPanePainterクラスが使われるように指定しました。

ちなみに,method属性で指定したルートペインは,フレームに貼られるコンポーネントです。ルートペインは二つのペインを持ちます。一方がコンテントペインで,もう一方がグラスペインです。

以前のSwingではフレームにコンポーネントを貼る時にframe.getContentPane().add(comp);のようにgetContentPaneメソッドをコールしてから,コンポーネント貼っていました。このgetContentPaneメソッドで取得できるのが,ルートペインに貼られているコンテントペインなのです。

このようなSwingの構造をある程度知らないと,XMLで指定する際どの領域になるのかがわからないのがつらいところです。