我正在做一些练习,以了解Java和Swing API。为什么在Disegno构造函数中有nullPointerException?我想打印两个矩形的坐标,但是它们似乎没有初始化。

import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Disegno extends JFrame{

    Disegno(){
        this.setSize(500, 500);
        this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
        MyPanel aba = new MyPanel();
        this.setContentPane(aba);
        this.setVisible(true);

        System.out.println(aba.rect.blue.x + "-" + aba.rect.blue.y);
        System.out.println(aba.rect.yellow.x + "-" + aba.rect.yellow.y);
    }

    public static void main(String[] args){
        new Disegno();
    }
}

class MyPanel extends JPanel{

    JPanel up, down;
    RectArea rect;

    MyPanel(){
        this.setLayout(new BorderLayout());

        up = new JPanel();
        this.add(up, BorderLayout.NORTH);
        up.setBackground(Color.red);
        up.setVisible(true);

        down = new JPanel();
        down.setBackground(Color.green);
        this.add(down, BorderLayout.SOUTH);
        down.setVisible(true);

        rect = new RectArea();
        this.add(rect, BorderLayout.CENTER);

        this.setVisible(true);
    }
}

class RectArea extends JPanel{

    Rectangle blue, yellow;
    boolean check = false;

    RectArea(){
        super();
        this.setVisible(true);
    }

    public void initRect(){
        blue = new Rectangle(0, 0, 100, 100);
        yellow = new Rectangle(this.getWidth(), this.getHeight(), 100, 100);
        System.out.println("ok");
    }

    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        if(check == false){
            this.initRect();
            check = true;
        }

        System.out.println(this.getWidth() + "-" + this.getHeight());
        g.setColor(Color.blue);
        g.fillRect(blue.x, blue.y, blue.width, blue.height);
        g.setColor(Color.yellow);
        g.fillRect(yellow.x - yellow.width, yellow.y - yellow.height, yellow.width, yellow.height);
    }
}

最佳答案

其他人则有益地建议了检测和避免NullPointerException的方法。不幸的是,您不能依赖何时调用paintComponent()的实现。代替,

  • 根据当前寡妇的大小确定所需的几何形状;在下面的示例中调整窗口的大小,以查看yellow似乎如何粘在右下角。
  • 因为MyPanel不包含其自身的组件,所以您应该覆盖getPreferredSize(),因为@nIcE cOw显示here
  • 使用pack()调整封闭的Window的大小。
  • 建立在event dispatch thread上。

  • 附录:我不明白为什么您要覆盖getPreferredSize()方法。
    JComponent的子类覆盖 getPreferredSize() ,以便 pack() 可以调整Window的大小以“适合其子组件的首选大小和布局”。这样,您不必担心用户是否使用其他字体。 MyPanel仅绘制几何形状,因此您是首选大小的老板。如here所讨论的,为了方便起见,演示可能会使用setPreferredSize(),但是您应该了解这样做的局限性。
    import java.awt.*;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    /**
    * @see https://stackoverflow.com/q/11376272/230513
    */
    public class Disegno extends JFrame {
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new Disegno();
                }
            });
        }
    
        Disegno() {
            this.setSize(500, 500);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
            MyPanel aba = new MyPanel();
            this.add(aba);
            this.pack();
            this.setLocationRelativeTo(null);
            this.setVisible(true);
        }
    
        class MyPanel extends JPanel {
    
            private JPanel up, down;
            private RectArea rect;
    
            MyPanel() {
                super(new BorderLayout());
    
                up = new JPanel();
                up.setBackground(Color.red);
                this.add(up, BorderLayout.NORTH);
    
                rect = new RectArea();
                this.add(rect, BorderLayout.CENTER);
    
                down = new JPanel();
                down.setBackground(Color.green);
                this.add(down, BorderLayout.SOUTH);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(320, 240);
            }
        }
    
        class RectArea extends JPanel {
    
            private Rectangle blue = new Rectangle(0, 0, 100, 100);
            private Rectangle yellow = new Rectangle(0, 0, 100, 100);
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                System.out.println(this.getWidth() + " x " + this.getHeight());
                g.setColor(Color.blue);
                g.fillRect(blue.x, blue.y, blue.width, blue.height);
    
                g.setColor(Color.yellow);
                int dx = getWidth() - yellow.width;
                int dy = getHeight() - yellow.height;
                g.fillRect(dx, dy, yellow.width, yellow.height);
            }
        }
    }
    

    09-12 09:22