WisdomSoft - for your serial experiences.

3.7 原点を変更する

Graphics オブジェクトの描画関連メソッドで使用する座標の原点の位置を変更します。

3.7.1 新しい原点

デフォルトで、Graphics オブジェクトの座標系は原点をコンポーネントの左上隅と設定しています。文字を描画するときなど、一般的な処理ではこの座標系で問題ありませんが、複雑な描画メカニズムを持つ特殊なソフトウェアなどを開発するとき、原点の位置が左上隅に固定されていることが問題になる可能性があります。例えば、グラフを描画するソフトウェアなどでは、原点を中央に配置したいと考えるかもしれません。

実は Graphics オブジェクトは原点を変更することができます。デフォルトではコンポーネントの左上隅に設定されていますが、これを現在の座標系を使って原点を移動させることができます。原点を移動した後の描画処理は、すべてこの原点情報に従って描画されます。特定のルーチンが描画する図形を、コードを操作することなく移動させたい場合などは、Graphics オブジェクトの原点を変更すれば良いでしょう。簡単に図形全体をシフトさせることができてしまいます。

原点を移動するには Graphics クラスの translate() メソッドを使います。

Graphics クラスの translate() メソッド
public abstract void translate(int x, int y)

x パラメータと y パラメータには、現在の座標系を使って新しい原点を指定します。

コード1
import java.applet.Applet;
import java.awt.*;

//<applet code="Test.class" width="400" height= "400"></applet>

public class Test extends Applet {
	public void paint(Graphics g) {
		Drawing(g);
		
		g.translate(80 , 50);
		Drawing(g);

		g.translate(30 , -30);
		Drawing(g);
	}

	private static final String TEXT = "Kitty on your lap";
	private void Drawing(Graphics g) {
		FontMetrics fm = g.getFontMetrics();
		int width = fm.stringWidth(TEXT);
		int height = fm.getHeight();

		g.drawRect(0 , 0 , (int)(width * 1.1) , (int)(height * 1.1));
		g.drawString(TEXT , (int)(width * 0.05) , (int)(fm.getAscent() * 1.05));
	}
}
実行結果
コード1 実行結果

コード1は、Graphics オブジェクトの原点 (0 , 0) から矩形の枠を描画し、その内部に文字を描画する Drawing() メソッドを定義しています。このメソッドは厄介なことに、描画位置を変更することができません。極めて固定的で、柔軟性の欠けたメソッドです。

このような状況で、Drawing() メソッド内のコードの変更を避けて描画位置を移動させなければならないとすれば、逆転の発想で描画位置を移動するのではなく原点そのものを移動させてしまえばよいのです。Test クラスの paint() メソッドを見れば、最初に呼び出した Drawing() メソッドは確かにコンポーネントの左上隅から描画しています。しかし、translate() メソッドで原点を移動し、再び Drawing() メソッドを呼び出せば、左上隅ではなく translate() メソッドで指定した新しい原点の位置に描画していることが確認できます。

もっとも、本来はグラフを書くときなどの利便上の問題を解決するために原点の移動を用いるべきで、描画位置を変更するために原点の移動を使うべきではありません。正しくは Drawing() メソッドが描画位置をパラメータから受け取り、柔軟に対応できるようにするべきでしょう。