paintComponent() 未被调用

paintComponent() not being called

这是一个小程序,应该(理论上)在屏幕上绘制一个球的图像。 问题是 paintComponent 似乎没有被调用。该程序由两个类.

组成
import java.awt.*;
import java.io.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.*;

public class ScreenSaver extends JPanel {
    private static final long serialVersionUID = 001;

    public static void main(String[] args) {
        new ScreenSaver();
    }
    public ScreenSaver() {
        new Window(1600, 900, "ScreenSaver", this);
    }
    //----------------------------------------------------------------------------------
    private static BufferedImage ball;
    public static BufferedImage getBallSprite() {
            try {
                 File pathToBall = new File("ball.png");
                 ball = ImageIO.read(pathToBall);
            } catch (IOException ex) {
                    ex.printStackTrace();
            }
            return ball;
    }
}
import java.awt.*;
import java.io.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.*;

public class Window extends Canvas {
private static final long serialVersionUID = 002;

    public Window(int width, int height, String title, ScreenSaver ScreenSaver) {
        JFrame frame = new JFrame(title);
        frame.setPreferredSize(new Dimension(width, height));
        frame.setMaximumSize(new Dimension(width, height));
        frame.setMinimumSize(new Dimension(width, height));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        repaint();
    }

    public void paintComponent(Graphics g) {
        System.out.println("Painting...");
        BufferedImage ball = ScreenSaver.getBallSprite();
        g.drawImage(ball, 0, 0, 100, 100, this);
  }
}

如您所见,我测试了是否使用控制台消息调用了 paintComponent。可悲的是,情况并非如此。有人可以解释一下吗?

java.awt.Canvas 没有继承自 JComponent 所以 paintComponent 不会被自动调用。您可以创建一个新的自定义 window 而不是创建一个以 Swing 为中心的组件

public class MyWindow extends JComponent {

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
      ...
}

难怪 paintComponent 没有被调用,因为 Canvas 没有实现您可以覆盖的 paintComponent。对于 canvas,您必须根据自己的目的覆盖 paint。在您的代码中,您同时使用了 JPanelCanvas,这根本没有必要。使用两者之一。

下面是一个 Canvas 的例子:

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

public class ScreenSaver extends Canvas{
    public static void main(String[] args) {
        JFrame window = new JFrame("Screensaver");
        window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        window.setResizable(false);

        ScreenSaver canvas = new ScreenSaver();
        canvas.setPreferredSize(new Dimension(1600, 900));
        canvas.setBackground(Color.BLACK);

        window.add(canvas);
        window.pack();
        window.setLocationRelativeTo(null);
        window.setVisible(true);
    }

    @Override
    public void paint(Graphics g){
        g.setColor(Color.GREEN);
        g.fillOval(100, 100, 100, 100);
    }
}

要覆盖的方法上面的注解Override确保编译器可以在覆盖的方法不存在或有拼写错误时发出警告消息。我希望这对你有进一步的帮助。