import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements Runnable{
private static final long serialVersionUID = 1L;
private final int WIDTH = 400;
private final int HEIGHT = 400;
private static BufferedImage ship;
private int shipX;
private int shipY;
private boolean running;
public GamePanel(){
super();
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);
requestFocus();
try {ship = ImageIO.read(new File("res/ship2.png"));}
catch (IOException e) {e.printStackTrace();}
running = true;
}
private void gameUpdate() {
shipX++;
shipY++;
}
@Override
public void run() {
while(running){
gameUpdate();
repaint();
try {Thread.sleep(3);}
catch (InterruptedException e){e.printStackTrace();}
}
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, WIDTH, HEIGHT);
g.drawImage(ship, shipX, shipY, 100, 100, null);
}
}
import javax.swing.JFrame;
public class Game extends JFrame{
private static final long serialVersionUID = 1L;
public Game(){
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setResizable(false);
GamePanel g = new GamePanel();
Thread t = new Thread(g);
t.start();
add(new GamePanel());
pack();
setVisible(true);
}
public static void main(String[] args) {
new Game();
}
}
I have read many answers to questions like mine, but I have been stuck with this for hours. If repaint()
should invoke overridden paintComponent()
, why am I seeing no animation at all? I mean most things work: if I put System.out.println("test")
I can see that thread is working and in debugging mode I see shipX
and shipY
values changing, but in the window the image is stuck at the beginning 0,0 coordinates. I've been trying everything from overriding paint();
and overriding both but nothing seems to get animation going.
Can anyone provide help?
The Java Docs Custom Painting Demo is very useful when learning about painting and I recommend you read it. Below is that same demo edited to move the ship in a straight line until it reaches a certain point on the panel.
This may not be the answer you were looking for but this helped me a lot when I was learning about paint.
package messaround;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Game {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Swing Paint Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
}
class MyPanel extends JPanel {
BufferedImage boat;
Timer timer;
private int boatX = 0;
private int boatY = 0;
private int boatW;
private int boatH;
public MyPanel() {
try {
boat = ImageIO.read(new File("res/ship2.png"));
} catch (IOException e) {
e.printStackTrace();
}
boatW=boat.getWidth();
boatH=boat.getHeight();
timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
moveBoat();
if(boatX>100){
timer.cancel();
timer.purge();
}
}} ,0, 30);
setBorder(BorderFactory.createLineBorder(Color.black));
}
public void moveBoat(){
repaint(boatX,boatY,boatW,boatH);
boatX++;
boatY++;
repaint(boatX,boatY,boatW,boatH);
}
public Dimension getPreferredSize() {
return new Dimension(250,200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(boat, boatX, boatY, this);
}
}