There are a couple of errors I can find in your program
-
You’re using a(Probably not in this case, as per @MadProgrammer’s comment below), this is just another approachnull layout
, please see Null layout is evil and the answers in this question to see why you should avoid its use. -
while (true) {
this line might block the Event Dispatch Thread (EDT) along with this line:Thread.sleep(16);
, See Lesson: Concurrency in Swing to learn more about and How to use Swing Timers. You should also place your program on the EDT which can be done:public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { //Your constructor here } }); }
-
You’re not calling
super.paintComponent()
on yourpaintComponent()
method of theWall
class which could break the paint chain, always call it first. -
You’re extending
JComponent
, it would be better to extendJPanel
and do custom painting over it using the Shapes API
With all of the above in mind, you can then have a code like this one:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class SingleAnimation {
private JFrame frame;
private Timer timer;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new SingleAnimation().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
Wall wall = new Wall(300, 0);
timer = new Timer(16, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
wall.moveWall(-2, 0);
}
});
timer.setInitialDelay(0);
timer.start();
frame.add(wall);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class Wall extends JPanel {
private int xCoord;
private int yCoord;
public int getxCoord() {
return xCoord;
}
public void setxCoord(int xCoord) {
this.xCoord = xCoord;
}
public int getyCoord() {
return yCoord;
}
public void setyCoord(int yCoord) {
this.yCoord = yCoord;
}
public Wall(int x, int y) {
this.xCoord = x;
this.yCoord = y;
}
public void moveWall(int xUnits, int yUnits) {
xCoord += xUnits;
yCoord += yUnits;
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLUE);
g2d.fill(new Rectangle2D.Double(xCoord, yCoord, 100, 20));
}
}
Which will produce a similar output like this one: