カスタムボーダー
ボーダーの拡張
AbstractBorder クラスを継承することで、新しいボーダーを作成できます
または、Border インターフェイスを実装する形でも良いでしょう
しかし、原則としては AbstractBorder を継承した方が設計面でスリムです
新しいボーダークラスがオーバーライドして特化するべき機能は
Border インターフェイスで宣言されている3つのメソッドです
ひとつは Border.getBorderInsets() メソッドです
public Insets getBorderInsets(Component c)
c には、このボーダのインセットの値を適用するコンポーネントを指定します
このメソッドは、新しい Insets オブジェクトを返します
インセットは、ボーダーが使用する境界や空間を表します
AbstractBorder クラスでは、デフォルトとして全ての値が 0 の Insets を返します
もうひとつは Border.isBorderOpaque() メソッドです
public boolean isBorderOpaque()
このメソッドは、ボーダーが透明か不透明かを知らせるための論理地を返します
が、これは昔の仕様で、今ではあまり使われることがありません
ボーダーは、インセットを全て塗りつぶす場合にのみ不透明であると解釈し
そうでなければ、透明であると考えます
AbstractBorder クラスのデフォルト実装では false (透明)を返します
残るひとつは Border.paintBorder() メソッドです
コンポーネントは、ボーダーの描画が必要なときにこのメソッドを呼び出します
public void paintBorder(
Component c , Graphics g ,
int x , int y , int width , int height
)
c はボーダが描画されるコンポーネント、g は対象の Graphics を指定します
x には、ペイントされたボーダの X 座標、y は Y 座標
width には横幅、height には高さをそれぞれ指定します
新しいボーダーは、このメソッドから得られた情報を元に
設定されているインセットの情報を利用してボーダーを描画します
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 DoubleBorder(Color.RED , 5));
getContentPane().add(panel);
}
}
class DoubleBorder extends AbstractBorder {
private Color color;
private int space;
public DoubleBorder(Color color , int space) {
this.color = color;
this.space = space;
}
public Insets getBorderInsets(Component c) {
return new Insets(space , space , space , space);
}
public void paintBorder(Component c , Graphics g ,
int x , int y , int w , int h) {
g.setColor(color);
g.drawRect(x , y , w - 1 , h - 1);
g.drawRect(
x + space , y + space ,
w - space * 2 - 1 , h - space * 2 - 1
);
}
}
このプログラムは、二重線のボーダーを作成しています
patinBorder() をオーバーライドすることによって、適切なタイミングで呼び出されたとき
渡された Graphics にインセットを参考に線を描画しています
このプログラムでは省略していますが
Graphics のプロパティを変更することに躊躇がある場合は
Graphics インスタンスをコピーしてから、そのコピーを利用して描画すると良いでしょう