gpt4 book ai didi

java - Repaint() 未调用 JComponent 类中的paintComponent()

转载 作者:行者123 更新时间:2023-12-01 18:20:35 25 4
gpt4 key购买 nike

我正在创建一个 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);
}

}

最佳答案

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

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

JComponent.addNotify()文档说明:

Notifies this component that it now has a parent component. When this method is invoked, the chain of parent components is set up with KeyboardAction event listeners. This method is called by the toolkit internally and should not be called directly by programs.

编辑:

为了避免破坏绘制链,请确保在 paintComponent() 的实现中调用 super.paintComponent()。欲了解更多详情,请参阅Performing Custom PaintingPainting in AWT and Swing

关于java - Repaint() 未调用 JComponent 类中的paintComponent(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27772139/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com