Java Repaint()未在JComponent类中调用paintComponent()

Java Repaint()未在JComponent类中调用paintComponent(),java,swing,jcomponent,Java,Swing,Jcomponent,我正在创建一个java应用程序,使用JComponent类来绘制。 我对repaint()方法没有启动paintComponent()有问题。 这可能是什么原因 代码: JComponent类: import java.awt.Color; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JComponent

我正在创建一个java应用程序,使用JComponent类来绘制。 我对repaint()方法没有启动paintComponent()有问题。 这可能是什么原因

代码:

JComponent类:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JComponent;
import javax.swing.Timer;

public class Display extends JComponent implements ActionListener{

    private final static int Width = 400;
    private final static int Height = 600;
    private long period;
    private Timer timer;

    private Background background;

    private boolean isRunning = false;

    public Display(long period) {
        this.period = period;
        setSize(Width, Height);
        prepeareUi();
        setOpaque(false);
    }

    public void addNotify() {
        if(!isRunning) {
            timer = new Timer((int)period, this);
            timer.start();
            isRunning = true;
        }
    }

    public void stop() {
        if(isRunning)
            isRunning = false;
    }

    private void prepeareUi() {
        background = new Background(Width, Height);
    }

    public void paintComponent(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, Width, Height);
        background.draw(g);
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        if(isRunning) {
            background.update();
            repaint();
            return;
        }

        System.exit(0);

    }

}
框架类别:

import javax.swing.JFrame;

public class Frame extends JFrame {

    private static final int DEFAULTFPS = 20;

    public Frame(long period) {
        prepearUI(period);
    }

    private void prepearUI(long period) {
        Display d = new Display(period);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(d);
        pack();
        setResizable(false);
        setVisible(true);
    }

    public static void main(String[]args) {
        String fpsS = null;
        if(args.length==1)
            fpsS = args[0];

        int fps = (fpsS != null) ? Integer.parseInt(fpsS) :  DEFAULTFPS;
        long period = (long) (1000.0/fps); //In Ms!

        Frame f = new Frame(period);
    }

}
背景类

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;


public class Background {

    private int ParentWidth;
    private int ParentHeight;

    private int width;
    private int height;

    private BufferedImage image;

    private float x = 0;
    private float y = 0;

    private final static float ANIMATIONSPEED = 1F;
    private final static int ANIMATION_RIGHT = 0;
    private final static int ANIMATION_LEFT = 1;

    private int animationway = 1;

    public Background(int W, int H) {
        ParentWidth = W;
        ParentHeight = H;
        prepeareImage();
    }

    private void prepeareImage() {
        width = 0; height = 0;
        try {
            image = ImageIO.read(getClass().getResource("UI\\background.png"));
            width = image.getWidth(null);
            height = image.getHeight(null);
        } catch (IOException e) {
            System.err.println("Background.png not found!");
        }
    }

    public void update() {
        if(animationway == ANIMATION_RIGHT) {
            x += ANIMATIONSPEED;
            if(x>=0F) {
                animationway = ANIMATION_LEFT;
            }
        }

        if(animationway == ANIMATION_LEFT) {
            x -= ANIMATIONSPEED;
            if(x<=width/-1+ParentWidth) {
                animationway = ANIMATION_RIGHT;
            }
        }
    }

    public void draw(Graphics g) {
        g.drawImage(image, (int) x, (int) y, null);
    }

}
导入java.awt.Graphics;
导入java.awt.image.buffereImage;
导入java.io.IOException;
导入javax.imageio.imageio;
公课背景{
私有int-ParentWidth;
私人身高;
私有整数宽度;
私人内部高度;
私有缓冲图像;
私有浮动x=0;
私有浮动y=0;
私有最终静态浮动动画速度=1F;
私有最终静态int动画_RIGHT=0;
私有最终静态int动画_LEFT=1;
私有int animationway=1;
公共背景(int W,int H){
ParentWidth=W;
父母身高=H;
预出生年龄();
}
私有void prebeareimage(){
宽度=0;高度=0;
试一试{
image=ImageIO.read(getClass().getResource(“UI\\background.png”);
宽度=image.getWidth(null);
高度=image.getHeight(null);
}捕获(IOE异常){
System.err.println(“找不到Background.png!”);
}
}
公共无效更新(){
如果(animationway==动画\右){
x+=动画速度;
如果(x>=0F){
animationway=动画\左;
}
}
如果(animationway==动画左){
x-=动画速度;

如果(x问题是您对
addNotify
的重写没有调用父实现。这破坏了许多事情,正确的重新绘制通知可能是其中之一。您可以通过向实现添加
super.addNotify();
来解决此问题

但是我根本不会碰
addNotify
。不要重写它。在构造函数中初始化计时器或添加一个父级可以调用的方法来启动计时器。您已经有了方法
stop()
,所以只需创建方法
start()

文件规定:

通知此组件它现在有一个父组件。当 方法时,父组件链将使用 KeyboardAction事件侦听器。此方法由工具箱调用 内部调用,不应由程序直接调用

编辑:


为避免中断绘制链,请确保在
paintComponent()的实现中调用
super.paintComponent()
。有关更多详细信息,请参阅和。

问题是您对
addNotify
的重写没有调用父级实现。这破坏了许多事情,正确的重新绘制通知可能是其中之一。您可以通过向实现中添加
super.addNotify();
来解决此问题

但是我根本不会碰
addNotify
。不要重写它。在构造函数中初始化计时器或添加一个父级可以调用的方法来启动计时器。您已经有了方法
stop()
,所以只需创建方法
start()

文件规定:

通知此组件它现在有一个父组件。当 方法时,父组件链将使用 KeyboardAction事件侦听器。此方法由工具箱调用 内部调用,不应由程序直接调用

编辑:


为避免中断绘制链,请确保在
paintComponent()的实现中调用
super.paintComponent()
。有关更多详细信息,请参阅和。

是否可以通过不调用super.paintComponent添加有关断开绘制链的注释您可以通过不调用super.paintComponent添加关于断开绘制链的注释使用getPreferredSize而不是setSize;在执行自定义绘制之前调用super.paintComponent使用getPreferredSize而不是setSize;call super.paintComponent,然后再执行自定义绘制