I am trying to make a simple animation in which a rectangle starts off the screen (on the right side of the right edge of the screen) and moves towards the left. So, in this case, my frame has a width of 1000 and the wall starts off at an x-value of 1100. Obviously, at first, the rectangle is not supposed to be visible to us. But as the rectangle moves to the left, it should eventually become visible. However, this animation doesn't do that. Even when the wall's x-value is within the bounds of the screen, it isn't being rendered.
I tried putting a println()
statement in the paintComponent()
method of the wall, and I discovered that the paintComponent()
wasn't getting called by the frame's repaint()
method. I figured that when the wall was first added to the frame, Swing decided that since it was off the screen it doesn't need to get rendered, and so even when the wall eventually gets on the screen Swing thinks that it doesn't need to get rendered.
I have tried revalidating and invalidating the frame and the component, but nothing has worked. Please help me to fix this. Below is the code:
package graphics.simpleAnimation;
public class Simple_Animation implements Runnable {
private UI ui; // The UI (frame)
private Wall wall; // Wall object that moves across the screen
private Simple_Animation() {
// Initialize the wall object (intentionally given an x value that is greater than the frame's width)
wall = new Wall(1100, 400, 200, 400);
// Initialize the UI (width is only 1000)
ui = new UI(1000, 600, "Geometry Dash");
// Add the wall to the ui (the frame)
ui.add(wall);
}
public void run() {
// Set the frame visible
ui.setVisible(true);
// Repaint the frame and move the wall
while (true) {
ui.repaint();
wall.moveWall(-2, 0);
try {
Thread.sleep(16);
} catch (InterruptedException IE) {
System.out.println(IE);
}
}
}
// Starts the program in a new thread
public static void main(String[] args) {
Simple_Animation simpleAnimation = new Simple_Animation();
new Thread(simpleAnimation).start();
}
}
package graphics.simpleAnimation;
import javax.swing.*;
import java.awt.*;
public class UI extends JFrame {
// Variables storing the width and height of the content pane (where the components are being rendered)
public int content_pane_width;
public int content_pane_height;
public UI(int frameW, int frameH, String frameTitle) {
setTitle(frameTitle);
setSize(frameW, frameH);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLayout(null);
content_pane_width = getContentPane().getWidth();
content_pane_height = getContentPane().getHeight();
}
@Override
public void paint(Graphics g) {
super.paint(g);
}
}
package graphics.simpleAnimation;
import java.awt.*;
import javax.swing.*;
public class Wall extends JComponent {
private int wallX;
private int wallY;
private int wallW;
private int wallH;
Wall(int x, int y, int sizeX, int sizeY) {
wallX = x;
wallY = y;
wallW = sizeX;
wallH = sizeY;
setSize(getPreferredSize());
}
public void moveWall(int moveX, int moveY) {
wallX += moveX;
wallY += moveY;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(wallW, wallH);
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
setLocation(wallX, wallY);
g2d.fillRect(0, 0, wallW, wallH);
}
}