ボーダー


コンポーネントの枠

これから紹介するボーダーに関連した技術は
GUI コンポーネントの設計において、Swing が極めて優秀だと感じる一面を見せてくれます

Windows の GUI のコンポーネントの設計を見ると
WIn32 API にしても .NET にしても、ボーダーはフラグとして選択します
確かにフラグによる方法は軽快で、分かりやすいのですが柔軟性に欠けます

独自のコンポーネントを設計する場合、多くのケースで枠も作成する必要がありますが
これを独自に実装したり、クラスの描画機能にハードコーディングしてしまうのは
あまり優れたオブジェクト指向設計とはいえないでしょう

Swing では、コンポーネントのボーダーは抽象化され、部品化されています
そのため、コンポーネントとは別にコーディングする必要がありますが
コンポーネントのボーダーは再利用可能であり、これは極めてオブジェクト指向的です

ボーダーは JComponent.setBorder() メソッドを通して
Swing コンポーネントにインストールされ、Swing は保有するボーダーを描画します

public void setBorder(Border border)

border には Border インターフェイスを実装するボーダーを指定します
Border は javax.swing.border で宣言されているインターフェイスです

public interface Border

このインターフェイスはボーダーをインストールしたコンポーネントが
ボーダーの描画を要求するために必要な基本的なメソッドを宣言しています

Swing のボーダーは javax.swing.border パッケージに含まれています
Border インターフェイスは、Swing における標準ボーダーの抽象クラス
javax.swing.border.AbstractBorder クラスに実装されています
public abstract class AbstractBorder
	extends Object implements Border, Serializable
この抽象クラスは Border の実装を行うと同時に
ボーダーの実体を抽象化する役割を持っています
例えばカスタムボーダーを作成する場合、このクラスを継承すると効率的でしょう
カスタムボーダーの作り方については後期します

基本的な枠は javax.swing.border.LineBorder クラスでしょう
このクラスは、直線のボーダーを実装します
java.lang.Object
  |
  +--javax.swing.border.AbstractBorder
        |
        +--javax.swing.border.LineBorder

public class LineBorder extends AbstractBorder
このクラスは、次のようなコンストラクタを公開しています

public LineBorder(Color color)
public LineBorder(Color color , int thickness)
public LineBorder(Color color , int thickness , boolean roundedCorners)

color はボーダーの色、thickness は太さ
roundedCorners はボーダの隅を丸くするかどうかを示すブール値を指定します
ボーダーのインスタンスを生成したら、コンポーネントの setBorder() で設定します
すると、コンポーネントが描画されると、指定したボーダーが表示されるでしょう
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class Test extends JApplet {
	public void init() {
		JPanel panel = new JPanel();
		panel.setBorder(new LineBorder(Color.RED , 5));

		getContentPane().add(panel);
	}
}


この図を見て分かるように、プログラムでは JPanel クラスを作成し
これに LineBorder を設定しています
LineBorder のインスタンスは、赤い直線に太さ 5 が指定されています
要求どおり、赤いボーダーがパネルに描画されていることが確認できます


エッチング

「エッチなのはいけないと思います!」
と、どこかの元戦闘用アンドロイドのようなことは言わずに聞いてください

エッチングボーダーを使えば、浮き彫りやくぼみのあるボーダーを実装できます
3次元的立体感を表現するには、最も簡単な方法でしょう
エッチングは javax.swing.border.EtchedBorder クラスが実装します
java.lang.Object
  |
  +--javax.swing.border.AbstractBorder
        |
        +--javax.swing.border.EtchedBorder

public class EtchedBorder extends AbstractBorder
このクラスは、次のようなコンストラクタを公開しています

public EtchedBorder()
public EtchedBorder(int etchType)
public EtchedBorder(Color highlight , Color shadow)
public EtchedBorder(int etchType , Color highlight , Color shadow)

etchType には、エッチングのタイプを表す値を指定します
この値は EtchedBorder クラスの静的フィールドで定義されています
highlight にはハイライト、shadow は陰影に用いられる色を指定します

etchType を指定しない場合は、デフォルトで彫り込みとなります
エッチングタイプは次のようなものがあります

フィールド定数解説
public static final int RAISED浮き彫りエッチング
public static final int LOWERED彫り込みエッチング
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class Test extends JApplet {
	public void init() {
		JPanel panel1 = new JPanel();
		JPanel panel2 = new JPanel();
		panel1.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
		panel2.setBorder(new EtchedBorder(EtchedBorder.RAISED));

		getContentPane().setLayout(new GridLayout(1 , 2));
		getContentPane().add(panel1);
		getContentPane().add(panel2);
	}
}


このプログラムは、浮き彫りと彫り込みのエッチングボーダーを表示します
色は指定していないので、デフォルトの背景を利用した色で表現されています


斜影ボーダー

射影ボーダーは、コンポーネントを立体的に見せるボーダーとして使うことができます
これは左と上のライン、右と下のラインの2ラインに分かれて立体を表現します

斜影ボーダーは javax.swing.border.BevelBorder で実装されます
java.lang.Object
  |
  +--javax.swing.border.AbstractBorder
        |
        +--javax.swing.border.BevelBorder

public class BevelBorder extends AbstractBorder
このクラスは、次のようなコンストラクタを公開しています

public BevelBorder(int bevelType)
public BevelBorder(int bevelType ,
	Color highlight , Color shadow
)
public BevelBorder(int bevelType ,
	Color highlightOuterColor , Color highlightInnerColor ,
	Color shadowOuterColor , Color shadowInnerColor
)
bevelType には、ボーダーの斜影タイプを指定します
highlight は斜影のハイライトに、shadow は斜影の陰影に使う色を指定します
highlightOuterColor は斜影の外側、highlightInnerColor は内側ハイライトの色を
shadowOuterColor は斜影の外側陰影、shadowInnerColor は内側陰影の色を指定します

ボーダーの色を指定しなかった場合は、コンポーネントの背景色を元に作られます
斜影タイプは BevelBorder クラスの静的フィールドとして定義されています

フィールド定数解説
public static final int RAISED浮き出し斜影
public static final int LOWEREDくぼみ斜影

名前と意味は、エッチングの時と同様です
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class Test extends JApplet {
	public void init() {
		JPanel panel1 = new JPanel();
		JPanel panel2 = new JPanel();
		panel1.setBorder(new BevelBorder(BevelBorder.LOWERED));
		panel2.setBorder(new BevelBorder(BevelBorder.RAISED));

		getContentPane().setLayout(new GridLayout(1 , 2));
		getContentPane().add(panel1);
		getContentPane().add(panel2);
	}
}


これが斜影ボーダーです。
コンポーネントを立体的に見せることができます

さらに、角の丸い斜影ボーダーを実装するために
BevelBorder を拡張した javax.swing.border.SoftBevelBorder クラスもあります
java.lang.Object
  |
  +--javax.swing.border.AbstractBorder
        |
        +--javax.swing.border.BevelBorder
              |
              +--javax.swing.border.SoftBevelBorder

public class SoftBevelBorder extends BevelBorder
このクラスのコンストラクタは BevelBorder() コンストラクタと同じシグネチャです
public SoftBevelBorder(int bevelType)
public SoftBevelBorder(
	int bevelType,
	Color highlight , Color shadow
)
public SoftBevelBorder(
	int bevelType,
	Color highlightOuterColor , Color highlightInnerColor ,
	Color shadowOuterColor , Color shadowInnerColor
)
引数の意味は BevelBorder() コンストラクタと同じなので省略します
これを用いれば、角の丸い斜影ボーダーを作ることができます
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class Test extends JApplet {
	public void init() {
		JPanel panel1 = new JPanel();
		JPanel panel2 = new JPanel();
		panel1.setBorder(new SoftBevelBorder(BevelBorder.LOWERED));
		panel2.setBorder(new SoftBevelBorder(BevelBorder.RAISED));

		getContentPane().setLayout(new GridLayout(1 , 2));
		getContentPane().add(panel1);
		getContentPane().add(panel2);
	}
}
SoftBevelBorder クラスの機能は、ほとんど BevelBorder と変わりません


タイトルボーダー

タイトル付きのボーダーを作成する方法は、Swing の高度な設計を目の当たりにします
タイトル付きボーダーは、Windows のグループボックスコントロールのような存在です
その形状は、ボーダーが表示する文字とボーダーラインで構成されます

論理的には、表示する文字と描画するラインの情報は実質的に分解されています
文字はフォントや色などを設定し、柔軟な表現力を持つべきですし
ラインは単純な線から斜影やエッチングであっても機能的に問題はありません

これを実現したのが javax.swing.border.TitledBorder クラスです
java.lang.Object
  |
  +--javax.swing.border.AbstractBorder
        |
        +--javax.swing.border.TitledBorder

public class TitledBorder extends AbstractBorder
このクラスは、非常に柔軟なタイトルつきボーダーを実現させます
以下のコンストラクタを見れば、それが理解できるでしょう
public TitledBorder(Border border)
public TitledBorder(Border border , String title)

public TitledBorder(
	Border border , String title ,
	int titleJustification , int titlePosition
)
public TitledBorder(
	Border border , String title ,
	int titleJustification , int titlePosition , Font titleFont
)
public TitledBorder(
	Border border , String title ,
	int titleJustification , int titlePosition ,
	Font titleFont , Color titleColor
)
border にはボーダーを、title にはボーダーに表示する文字列を指定します
titleJustification はタイトルの位置揃え、titlePosition はタイトルの位置を指定します
titleFont はタイトル文字列のフォント、titleColor はタイトル文字の色を指定します

まず、重要なのはボーダーは外部の他のボーダーを指定できるということです
そのため、斜影やエッチングなどのボーダーを自由に入れ替えることができます
さらに、タイトル文字の位置やフォント、色も自由に変更することができます

titleJustification には次の TitledBorder の静的フィールドを指定できます
タイトルはボーダーの左、中央、右のいずれかによせられます

フィールド定数解説
CENTER タイトルテキストをボーダラインの中央に配置します
DEFAULT_JUSTIFICATION タイトルテキストにデフォルトの位置揃えを使用します
LEADING 左から右方向の場合はタイトルテキストをボーダラインの左側に
右から左方向の場合はボーダラインの右側に配置します
LEFT タイトルテキストをボーダラインの左側に配置します
RIGHT タイトルテキストをボーダラインの右側に配置します
TRAILING 左から右方向の場合はタイトルテキストをボーダラインの右側に
右から左方向の場合はボーダラインの左側に配置します

titlePosition はタイトルの垂直位置を指定します
ここには、次の TitledBorder クラスの静的フィールドを指定できます

フィールド定数解説
ABOVE_BOTTOM タイトルをボーダのボトムラインより上に配置します
ABOVE_TOP タイトルをボーダのトップラインより上に配置します
BELOW_BOTTOM タイトルをボーダのボトムラインより下に配置します
BELOW_TOP タイトルをボーダのトップラインより下に配置します
BOTTOM タイトルをボーダのボトムラインの中央に配置します
DEFAULT_POSITION タイトルテキストにデフォルトの垂直方向配置を使用します
TOP タイトルをボーダのトップラインの中央に配置します
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class Test extends JApplet {
	public void init() {
		JPanel panel = new JPanel();
		panel.setBorder(
			new TitledBorder(
				new LineBorder(Color.RED) ,
				"Kitty on your lap" ,
				TitledBorder.CENTER  ,
				TitledBorder.TOP
			)
		);
		getContentPane().add(panel);
	}
}


このプログラムは、指定した文字列のタイトルで、赤い LineBorder をボーダーとし
ボーダーラインの上部中央にタイトルテキストを表示します


複合ボーダー

Swing のボーダーの柔軟さはこれで終わりません。
さらに、複数のボーダーを合成する機能までが備えられているのです
これは複合ボーダーと呼ばれ、2つの Border を組み合わせます

複合ボーダーは javax.swing.border.CompoundBorder クラスで実装されます
java.lang.Object
  |
  +--javax.swing.border.AbstractBorder
        |
        +--javax.swing.border.CompoundBorder

public class CompoundBorder extends AbstractBorder
このクラスは、次のようなコンストラクタを公開しています

public CompoundBorder()
public CompoundBorder(Border outsideBorder , Border insideBorder)

outsideBorder には外側のボーダーを
insideBorder には入れ子にする内側のボーダーを指定します

指定するのは Border インターフェイスなので、完全に抽象化されています
Swing が実装している定義済みのボーダーでもかまいませんし
カスタムボーダーでも良いし、CompoundBorder を入れ子にすることもできます
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class Test extends JApplet {
	public void init() {
		JPanel panel = new JPanel();
		panel.setBorder(
			new CompoundBorder(
				new LineBorder(Color.RED , 3) ,
				new BevelBorder(BevelBorder.RAISED)
			)
		);
		getContentPane().add(panel);
	}
}


このプログラムは、単純なボーダーの内側に斜影ボーダーを入れ子にしています



前のページへ戻る次のページへ