在JFrame上绘画有效,但无论如何都会抛出NullPointerException

时间:2013-12-05 02:24:29

标签: java swing nullpointerexception jframe paint

窗口显示并按预期工作,但由于某种原因它仍然给我一个NullPointerException。实际上是两个。这是代码:

public class SwagFrame extends JFrame {

  public SwagFrame() {super("Swag");}

  public void paint(Graphics g) {
      Image bg = null;

      try {
        bg = ImageIO.read(new File("swag.png"));
      } catch (IOException e) {
        System.out.println("Swag not turned on");
        System.exit(-1);
      }

      g.drawImage(bg, 0, 0, null); // exception here
      g.setColor(Color.GREEN);
      g.fillOval(250, 250, 100, 100);
  }

  public static void main(String[] args) {
    SwagFrame frame = new SwagFrame();

    frame.setVisible(true);
    frame.setSize(525, 525);
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);

    frame.paint(null); // exception here
  }
}

如果paint()在其参数中需要一个对象,为什么它仍然可以工作但在事后抛出异常?

1 个答案:

答案 0 :(得分:3)

我做了两件事。我将SwagFrame设为JPanel而不是JFrame,因此我可以使用paintComponent方法删除frame.paint(null),然后将null中的drawImage更改为{{ 1}}。代码现在工作正常。

this

此外,如果要设置图像的大小,可以将其作为参数传递给.drawImage()方法

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class SwagFrame extends JPanel {
    public SwagFrame() {

    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        BufferedImage bg = null;

        try {
            bg = ImageIO.read(new File("icons/stacko/stackoverflow1.png"));
        } catch (IOException e) {
            System.out.println("Swag not turned on");
            //System.exit(-1);
        }


        g.drawImage(bg, 0, 0, this); // exception here
        g.setColor(Color.GREEN);
        g.fillOval(250, 250, 100, 100);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new SwagFrame());
        frame.setSize(525, 525);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        //frame.paint(g); // exception here
    }
}

还有一件事,请确保图像位于正确的文件位置。

正如@MadProgrammer在评论中所说:

  

“通常,顶级容器不是双缓冲的,其中Swing组件(从JComponent扩展)是。顶级容器有多个层放在它们的顶部(分层窗格,内容窗格和玻璃窗格),通常,当绘制子组件时,父容器不需要这样会导致出现脏涂料。此外,通常不鼓励从JFrame扩展,因为你永远不会实际上添加任何其他功能

     

OPs代码不起作用的原因(因为你似乎已经被引用)是因为他们将一个空值传递给paint方法,当他们试图访问“g”时,它会抛出一个NPE,然而,在重绘管理器调度它的绘制请求时,paint方法被传递了一个有效的图形引用,这意味着它能够正常工作......而且,OP不是调用super.paint,对它们不好“ - @MadProgrammer