precargar imágenes en Java

Entonces, estoy programando un juego básico de TowerDefense. Se está combinando muy bien, pero estoy atascado tratando de precargar imágenes. Mi problema es que cuando llamo al método de pintura para mi clase Canvas (se extiende JPanel) abre un hilo llamado "Image Fetcher x" donde 'x' es un número que comienza con 0 y sube para varias instancias del hilo . Según tengo entendido, este hilo toma las imágenes de mis variables de imagen, las ubica en el disco, las carga en la RAM para que mi juego las muestre y luego las dibuja.
Esto funciona bien, sin embargo, en el medio del juego, hay momentos en los que no aparece nada porque el método de dibujo al que llamo está intentando dibujar una imagen que no se ha cargado. El juego sigue siendo efectivo, pero la representación visual está en mal estado porque el jugador básicamente ve un bloque de hierba disparando a un enemigo. Entonces, de repente, la imagen se carga y se dibuja y se ve normal.

Esto está bien y todo, pero quiero poder precargar todos los recursos (y posiblemente hacer una pantalla de carga para que el jugador sabe que el juego se está cargando) para que las imágenes no cargadas no destruyan la ilusión del juego, si eso tiene sentido. He intentado usar un MediaTracker, eso no funcionó. He investigado esto y parece que no puedo encontrar nada en esto.

Mi código actual consiste en matrices de imágenes de un mapa de imágenes. Cada imagen en una matriz se dibuja en el lienzo de acuerdo con ciertos identificadores que le indican al juego qué azulejo / torre dibujar. Estoy usando la clase java.awt.Image para almacenar mis imágenes. Entonces, ¿hay alguna forma de precargar mis imágenes para que no tengan que cargarse a mitad del juego?
¡Gracias

Editar
Código









for(int y=0; y<tileMap.length; y++) {
    for(int x=0; x<tileMap[y].length; x++) {
        tileMap[y][x] = new ImageIcon("res/tileMap.png").getImage();
        tileMap[y][x] = createImage(new FilteredImageSource(tileMap[y][x].getSource(), new CropImageFilter(x * Room.blockSize, y * Room.blockSize, Room.blockSize, Room.blockSize))); 
    }
}

public void paintcomponent(Graphics g) {
    g.drawImage(tileMap[1][2], 5, 7, null);
}

Esa es una versión simplificada, tengo alrededor de 1500 líneas, así que no creo que quieras ver todo eso, jajaja. Básicamente, solo creo las variables de imagen y luego las dibujo. En el momento de dibujarlos, se inicia un hilo Image Fetcher, carga la imagen y luego desaparece una vez que la imagen ha terminado de cargarse. Mientras se carga la imagen (y el hilo Image Fetcher está activo), el método drawImage no dibuja nada ya que la imagen no está precargada en la RAM. Sin embargo, una vez que haya terminado de cargar la imagen, el método drawImage dibuja la imagen correcta y el hilo Image Fetcher ya no está activo. ¿Hay alguna manera de iniciar el proceso de obtención de imágenes para que todo esto sucedaantes d comenzando el programa?
También he intentado dibujar todo al principio, eso no funcionó ya que el programa se ejecuta demasiado rápido para que los Image Fetchers carguen con éxito cada imagen antes de que el usuario juegue. idk, los Image Fetchers son complicados. Solo necesito saber cómo precargar imágenes en la RAM.