Previous | Next | Trail Map | Creating a User Interface | グラフィックスを扱う


形状を描画する

Graphics クラスは、以下のような種類の形状を描画するためのメソッドを定義する。

多角形とラインを除くすべての形状は、外接長方形を使用して指定される。矩形を理 解すると他の形状の描画も比較的簡単に行えるため、このページでは矩形の描画について集中的に説明する。

例 1: 単純な矩形の描画

前のページのアプレットは draw3DRect()fillRect() メソッドを使用してそのインタフェースを描画していた。 そのアプレットを再びここに示す。

そのコードも参照できる。 以下に、描画に関するコード部分を示す。

//FramedArea (Panel サブクラス) で:
public void paint(Graphics g) {
    Dimension d = size();
    Color bg = getBackground();

    //アプレットの周りに適当なフレームを描く。
    g.setColor(bg);
    g.draw3DRect(0, 0, d.width - 1, d.height - 1, true);
    g.draw3DRect(3, 3, d.width - 7, d.height - 7, false);
}

//CoordinateArea (Canvas サブクラス) で:
public void paint(Graphics g) {
    //ユーザがクリックしたら、その場所に非常に小さな矩形をペイントする
    if (point != null) {
        g.fillRect(point.x - 1, point.y - 1, 2, 2);
    }
}

アプレットは FramedArea オブジェクトを作成 (および保持) し、それが今度は CoordinateArea オブジェクトを作成 (および保持) する。 draw3DRect() への最初の呼び出しにより、FramedArea の描画領域と 同じ大きさの矩形が作成される。true 引数は、矩形が浮き上がったよ うに表示することを指示するものである。 draw3DRect() への 2 回目の呼び出しにより、わずかに小さいもう 1 つの矩形が作成される。これには矩形が沈んだように表示することを指示した false が指定されている。2 つの呼び出しが合わさって、 CoordinateArea をもつフレームが浮き上がったように見える効果を生み出している 。(FramedArea は、CoordinateArea の描画領域が FramedArea の数ピクセル分内側 にくるように insets() メソッドを実装している。)

CoordinateArea は fillRect() を使用して、ユーザがクリックする場 所に 2 x 2 ピクセルの矩形を描いている。

例 2: 矩形を使って、選択された領域を示す。

ここで、描画プログラムに選択を実装するときの基本として使用できるアプレットを 示す。 ユーザがマウスをドラッグすると、このアプレットは連続的に矩形を表示する。 矩形はユーザが最初にマウスボタンを押したカーソル位置から始まり、現在のカーソ ル位置で終了する。

アプレットの コードも参照できる。 以下に、重要な新しいコード部分を示す。

class SelectionArea extends Canvas {
    . . .

    public boolean mouseDown(Event event, int x, int y) {
        currentRect = new Rectangle(x, y, 0, 0);
        repaint();
        return false;
    }

    public boolean mouseDrag(Event event, int x, int y) {
        currentRect.resize(x - currentRect.x, y - currentRect.y);
        repaint();
        return false;
    }

    public boolean mouseUp(Event event, int x, int y) {
        currentRect.resize(x - currentRect.x, y - currentRect.y);
        repaint();
        return false;
    }

    public void paint(Graphics g) {
        Dimension d = size();

        //currentRect が存在していれば、手前に矩形をペイントする。
        if (currentRect != null) {
            Rectangle box = getDrawableRect(currentRect, d);
            controller.rectChanged(box);

            //ボックスの輪郭を描く。
            g.drawRect(box.x, box.y, box.width - 1, box.height - 1);
        }
    }

    Rectangle getDrawableRect(Rectangle originalRect, Dimension drawingArea) 
{
        . . .
        //矩形の幅と高さが正の数であることを確認する。
        . . .
        //矩形が描画領域を超えないようにする。
        . . .
    }
}

コードからわかるように、SelectionArea は currentRect という Rectangle オブジェクトを使って、現在選択されている矩形を把握する。 currentRect は、ユーザがマウスをドラッグしている間、同じ起点 (currentRect.xcurrentRect.y) を保持するよう実装 されている。 つまり、矩形の高さと幅が負の数にもなり得るということである。

しかし、drawXxx()fillXxx() メソッドは、高さまたは幅が負であれば何も描画しない。このため、SelectionArea が矩形を描く場合、幅と高さが正となるように矩形の左上の頂点を指定しなければな らない。 SelectionArea クラスは、左上の頂点を導くために必要な計算を実行する、 getDrawableRect() メソッドを定義している。 getDrawableRect() メソッドは、矩形がその描画領域の境界を超えな いようにする役割ももつ。 ここで再び、ソースコード へのリンクを示す。 getDrawableRect() の定義はリンク先ファイルの最後に記載されている。

注: x、y、高さ、幅の値を負や、描画領域よりも大きくなるように指定することも、まっ たく違反ではない。 描画領域の外にある値は、描画領域に合わせて切り取られるのでたいして問題ではな く、形状の一部が見えないだけである。 高さまたは幅が負の場合は、その形状がまったく描画されないだけでる。

例 3:形状サンプラ

次のアプレットは、描画と塗りつぶしの対象となるすべての形状を示している。

読者が使用している Applet ビューワのデフォルトのフォントがあまり小さくなけれ ば、上記のアプレットで表示されたテキストは所々見にくくなっているかもしれない 。 語句はそれぞれがいちばん手前に描かれる上、このアプレットは境界を保護する insets() メソッドを使用していないため、テキストがアプレットの周 りのフレームにかかったりするのである。 次のページでは、テキストを所定のスペースに当てはめる方法を説明し、上の例を改 良する。

形状を描画するアプレットの コードも参照 できる。 ここでは、幾何学形状を描くコード部分だけを示す。rectHeightrectWidth 変数は、それぞれの形状が描かれる領域のサイズをピクセ ル単位で指定する。x 変数は形状ごとに変えられ 、形状が重ならないようにしている。

Color bg = getBackground();
Color fg = getForeground();
. . .

// drawLine()
g.drawLine(x, y+rectHeight-1, x + rectWidth, y); // x1, y1, x2, y2
. . .

// drawRect()
g.drawRect(x, y, rectWidth, rectHeight); // x, y, width, height
. . .

// draw3DRect()
g.setColor(bg);
g.draw3DRect(x, y, rectWidth, rectHeight, true);
g.setColor(fg);
. . .

// drawRoundRect()
g.drawRoundRect(x, y, rectWidth, rectHeight, 10, 10); // x, y, w, h, arcw, 
arch
. . .

// drawOval()
g.drawOval(x, y, rectWidth, rectHeight); // x, y, w, h
. . .

// drawArc()
g.drawArc(x, y, rectWidth, rectHeight, 90, 135); // x, y, w, h
. . .

// drawPolygon()
Polygon polygon = new Polygon();
polygon.addPoint(x, y);
polygon.addPoint(x+rectWidth, y+rectHeight);
polygon.addPoint(x, y+rectHeight);
polygon.addPoint(x+rectWidth, y);
//polygon.addPoint(x, y); //don't complete; fill will, draw won't
g.drawPolygon(polygon);
. . .

// fillRect()
g.fillRect(x, y, rectWidth, rectHeight); // x, y, width, height
. . .

// fill3DRect()
g.setColor(bg);
g.fill3DRect(x, y, rectWidth, rectHeight, true);
g.setColor(fg);
. . .

// fillRoundRect()
g.fillRoundRect(x, y, rectWidth, rectHeight, 10, 10); // x, y, w, h, arcw, 
arch
. . .

// fillOval()
g.fillOval(x, y, rectWidth, rectHeight); // x, y, w, h
. . .

// fillArc()
g.fillArc(x, y, rectWidth, rectHeight, 90, 135); // x, y, w, h
. . .

// fillPolygon()
Polygon filledPolygon = new Polygon();
filledPolygon.addPoint(x, y);
filledPolygon.addPoint(x+rectWidth, y+rectHeight);
filledPolygon.addPoint(x, y+rectHeight);
filledPolygon.addPoint(x+rectWidth, y);
//filledPolygon.addPoint(x, y);
g.fillPolygon(filledPolygon); 


Previous | Next | Trail Map | Creating a User Interface | グラフィックスを扱う