0

GRect と GOval を使用する GObject クラスを使用して単純な顔を作成しています。GRect と GOval を、getWidth() と getHeight() をインスタンス変数として記述したのと同じ座標に固定する必要があります。そうしてもエラーは表示されませんが、キャンバスに結果がありません。getWidth() と getHeight() をローカル変数として記述した場合にのみ結果が得られます。インスタンス変数の効果が表示されないのはなぜですか?

/*
 * This is section 2 problem 2 to draw a face using GRect amnd GOval. The face is     centred in the canvas.
 * PS: The face is scalable w.r.t. canvas.
*/
package Section_2;
import java.awt.Color;
import java.awt.Graphics;

import acm.graphics.GRect;
import acm.program.GraphicsProgram;

/*
 * creates a robot face which is centered in the canvas.
 */
public class RobotFace extends GraphicsProgram{

private static final long serialVersionUID = 7489531748053730220L;

//canvas dimensions for centering
int _canvasWidth = getWidth();
int _canvasHeight = getHeight();
public void run(){

    removeAll();    //to make sure multiple instances of graphic are not drawn during resize as an effect of overriding Java paint method
    //draw objects
    createFace();

}

//currently only createFace() is implemented
/*
 * creates a rect which is centred in the canvas
 */
private void createFace() {

    //canvas dimensions for centering
    //int _canvasWidth = getWidth();
    //int _canvasHeight = getHeight();

    //make the face scalable
    int _faceWidth = _canvasWidth  / 6;
    int _faceHeight = _canvasHeight / 4;
    //to center the face
    int _faceX = (_canvasWidth - _faceWidth)/2;
    int _faceY = (_canvasHeight - _faceHeight)/2;

    GRect _face = new GRect(_faceX , _faceY, _faceWidth, _faceHeight);
    _face.setFilled(true);
    _face.setColor(Color.BLUE);
    add(_face);
}

/*
 * (non-Javadoc)
 * @see java.awt.Container#paint(java.awt.Graphics)
 * to override Java inherited paint method to retain graphic after resizing  
 */
public void paint(Graphics g) {
    this.run();
    super.paint(g);
}    
}

getWidth() と getHeight() のローカル変数のコメントを外すと、 Rect が取得されます。それ以外の場合、キャンバスには影響しません。

4

3 に答える 3

1

インスタンス変数は、コンストラクターの外で初期化しないでください。スーパークラスが完全に初期化される前に getXXX メソッドが呼び出され、0 が返される場合があります。

編集 :

私が意味していたのは、メソッドを呼び出す前に親クラスを正しく設定するために、クラスコンストラクター内でインスタンス変数をより適切に初期化する必要があるということです:

 public class RobotFace extends GraphicsProgram{

 //canvas dimensions for centering
 int _canvasWidth =0;
 int _canvasHeight = 0;

 public RobotFace() {
   super();
   _canvasWidth = getWidth();
   _canvasHeight = getHeight();
 }
 [...]

とにかく、ここでは 0 の値を修正するという保証はありません。これは、グラフィックス オブジェクトが表示メカニズムのために特定のライフサイクルを持つことが多いため、コンストラクターの呼び出し後に高さと幅が初期化されない可能性があるためです。

于 2013-03-28T16:03:21.413 に答える
0

GObject が初期化される前に getWidth() と getHeight() を使用していると誤解され、getWidth() が 0 を返すようになっていました。開始されたのは、createFace()、createMout() などのすべてのメソッドにローカルの getWidth() を使用することでした。このプログラムは機能しますが、多くのコピーペーストが必要です。したがって、別のクラス RobotFace2 では、run() 内で GObjects を作成しました。つまり、createFace() などの新しいメソッドを作成しませんでした。この方法では、getWidth() を run() 内で 1 回だけ入力する必要があり、目と口の GRect をアンカーすることができました。 GRect に直面します。RobotFace2 も機能します。

RobotFaceRobotFace2

于 2013-03-29T04:46:51.260 に答える
0

問題は、初期化時にgetWidth()and getHeight()= 0であることです。RobotFaceこれらの行をクラス レベルで削除し、createFaceメソッドでコメントを解除します。

int _canvasWidth = getWidth();
int _canvasHeight = getHeight();
于 2013-03-28T16:20:37.027 に答える