问题
So I'm moving an image in Java2D and it bounces aswell. For some reason, it always leaves behind a trail of old images. How could I fix this?
Main class:
package org.main.graphics;
import java.awt.Graphics;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import org.main.entity.Entity;
import org.main.entity.Loael;
@SuppressWarnings("serial")
public class GameWindow extends JFrame implements Runnable {
private List<Entity> entities = new ArrayList<Entity>();
private Thread animator;
public GameWindow() throws IOException {
super("Game");
setSize(640, 480);
setVisible(true);
setResizable(false);
setLocationRelativeTo(null);
revalidate();
entities.add(new Loael(500, 400));
animator = new Thread(this);
animator.start();
}
public void paint(Graphics g) {
for (Entity entity : entities) {
try {
g.drawImage(entity.getImage(), entity.getX(), entity.getY(),
this);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
while (true) {
for (Entity entity : entities) {
entity.animate(getBounds());
repaint();
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
}
}
}
Example of what's wrong:

回答1:
Don't paint directly on JFrame
. Instead, use JPanel
or extension of JComponent
. For painting override paintComponent()
rather than paint()
. Don't forget to call super.paintComponent(g);
, otherwise you will encounter the same behavior as in your example - the previous result of drawImage()
is not cleared and the trail remains.
Take a look at Performing Custom Painting tutorial, and Closer Look at the Paint Mechanism section in particular, for more details.
Consider the following example that animates image in JPanel
using Swing timer:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class AnimateDemo {
private static void createAndShowUI() {
try {
Image image = ImageIO.read(new URL(
"http://duke.kenai.com/iconSized/duke.gif"));
final MyPanel panel = new MyPanel(image);
JFrame frame = new JFrame("AnimateDemo");
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
ActionListener timerAction = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
panel.animate();
}
};
Timer timer = new Timer(10, timerAction);
timer.setRepeats(true);
timer.start();
} catch (IOException e) {
e.printStackTrace();
}
}
static class MyPanel extends JPanel {
private Image image;
private int coordinateX = 0;
private int coordinateY = 0;
private boolean incrementX = true;
private boolean incrementY = true;
public MyPanel(Image image) {
this.image = image;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(image, coordinateX, coordinateY, this);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
public void animate() {
if (image != null) {
if (image.getWidth(this) + coordinateX > getWidth()) {
incrementX = false;
}
if (coordinateX < 0) {
incrementX = true;
}
if (incrementX)
coordinateX++;
else
coordinateX--;
if (image.getHeight(null) + coordinateY > getHeight()) {
incrementY = false;
}
if (coordinateY < 0) {
incrementY = true;
}
if (incrementY)
coordinateY++;
else
coordinateY--;
repaint();
}
}
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
来源:https://stackoverflow.com/questions/12332377/java2d-removing-old-pixels-after-moving-image