我正在创建一个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);
}
}
答案 0 :(得分:4)
问题是你的addNotify
覆盖没有调用父实现。这打破了许多事情,适当的重新通知可能就是其中之一。您可以通过向您的实施添加super.addNotify();
来解决此问题。
但我根本不会碰addNotify
。不要覆盖它。在构造函数中初始化计时器或添加父可以调用以启动计时器的方法。您已经拥有方法stop()
,因此只需创建方法start()
即可。
通知此组件它现在有一个父组件。当这个 调用方法,设置父组件链 KeyboardAction事件侦听器。该方法由工具包调用 在内部,不应该由程序直接调用。
编辑:
为避免破坏油漆链,请务必在super.paintComponent()
的实施中致电paintComponent()
。有关详细信息,请参阅Performing Custom Painting和Painting in AWT and Swing。