0

我正在使用 GObject 类创建一个简单的面孔,该类将使用 GRect 和 GOval。我希望 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。因此,确保在 GObject 获得的范围内调用 getWidth() 的唯一方法发起是为每个方法(如 createFace()、createMouth())使用本地 getWidth()。该程序确实有效,但涉及大量复制粘贴。因此,在替代类 RobotFace2 中,我在 run() 中创建了 GObject,即没有为 createFace() 等创建新方法。这样 getWidth() 只需在 run() 中键入一次,并且眼睛和嘴巴 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 回答