JComponent deja de procesarse una vez que sale de la pantalla

Estoy tratando de hacer una animación simple en la que un rectángulo comienza en la pantalla (en el lado derecho del borde derecho de la pantalla) y se mueve hacia la izquierda. Entonces, en este caso, mi marco tiene un ancho de 1000 y la pared comienza con un valor de x de 1100. Obviamente, al principio, no se supone que el rectángulo sea visible para nosotros. Pero a medida que el rectángulo se mueve hacia la izquierda, eventualmente debería hacerse visible. Sin embargo, esta animación no hace eso. Incluso cuando el valor x de la pared está dentro de los límites de la pantalla, no se representa.

Traté de poner unprintln() declaración en elpaintComponent() método de la pared, y descubrí que elpaintComponent() no estaba siendo llamado por el marcorepaint() método. Pensé que cuando la pared se agregó por primera vez al marco, Swing decidió que, dado que estaba fuera de la pantalla, no era necesario renderizarlo, por lo que incluso cuando la pared finalmente aparece en la pantalla, Swing piensa que no necesita ser procesado

He intentado revalidar e invalidar el marco y el componente, pero nada ha funcionado. Por favor, ayúdame a arreglar esto. Debajo está el código:

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);
    }
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta