Las imágenes en paintComponent solo aparecen después de cambiar el tamaño de la ventana

Quiero usar paintComponent(Graphics g) para pintar algunas imágenes usando un ciclo for. Sin embargo, el JFrame simplemente aparece como una pantalla en blanco, y solo muestra el fondo negro y las imágenes después de cambiar el tamaño de la ventana.

 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.io.*; import javax.imageio.*; import java.awt.geom.*; import java.awt.image.BufferedImage; import java.awt.Graphics; import java.util.Scanner; public class SimpleAdventure { private JFrame frame; private CardLayout cards; private Container c; private DrawPanel1 gamepanel; private BufferedImage greentiles, pinktiles, sandtiles, charsprites; private Image left1, right1, left2, right2, front; private Image pinkbg, greenbg, sandbg; private Image pinktop, greentop, sandtop; private int charx, chary; public SimpleAdventure() {} public static void main (String [] args) { SimpleAdventure retro = new SimpleAdventure(); retro.run(); } public void run() { frame = new JFrame("Simple Adventure"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(576, 576); frame.setVisible(true); // frame.setResizable(false); getImage(); c = frame.getContentPane(); cards = new CardLayout(); c.setLayout(cards); gamepanel = new DrawPanel1(); gamepanel.setBackground(Color.black); c.add(gamepanel, "Panel 1"); } public void getImage() { try { greentiles = ImageIO.read(new File("greenTiles.png")); pinktiles = ImageIO.read(new File("pinkTiles.png")); sandtiles = ImageIO.read(new File("sandTiles.png")); charsprites = ImageIO.read(new File("charactersheet.png")); } catch(IOException e) { e.printStackTrace(); } left1 = charsprites.getSubimage(18, 0, 6, 6); left2 = charsprites.getSubimage(24, 0, 6, 6); right1 = charsprites.getSubimage(0, 0, 6, 6); right2 = charsprites.getSubimage(6, 0, 6, 6); front = charsprites.getSubimage(12, 0, 6, 6); greenbg = greentiles.getSubimage(240, 0, 16, 16); sandbg = sandtiles.getSubimage(240, 0, 16, 16); pinkbg = pinktiles.getSubimage(240, 0, 16, 16); greentop = greentiles.getSubimage(224, 0, 16, 16); sandtop = sandtiles.getSubimage(224, 0, 16, 16); pinktop = pinktiles.getSubimage(224, 0, 16, 16); } class DrawPanel1 extends JPanel implements KeyListener { // private BottomPanel lower; public DrawPanel1() { /*this.setLayout(new BorderLayout()); lower = new BottomPanel(); this.add(lower, BorderLayout.SOUTH);*/ addKeyListener(this); } public void paintComponent(Graphics g) { super.paintComponent(g); for(int i = 0; i < 7; i++) { g.drawImage(greentop, 0 + (i * 96), 480, 96, 96, this); } System.out.println("check"); } public void keyPressed(KeyEvent e) { } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } } } 

frame.pack() llamar a frame.pack() para hacer el diseño inicial. Al cambiar el tamaño de la ventana, el diseño se arregla automáticamente, pero frame.setSize(...) no lo hace *.

Mueva frame.setVisible(true) al final de su método de run (es decir, después de haber construido todos los elementos de UI) y ponga frame.pack() justo antes de frame.setVisible(true) . (Gracias a Hovercraft y MadProgrammer por señalar esto)

* Al menos, no lo hace si el marco no es visible. Podría funcionar si el marco ya está visible; pruébalo y mira.

EDITAR: Ahora que volví a leer el javadoc, probablemente no quieras el pack después de todo, cambiará el tamaño del marco por ti. Sin probarlo, supongo que mover setVisible hasta el final funcionará; si no lo hace, utilice revalidate lugar de pack para que se ejecute el motor de diseño.

EDIT 2: Ahora que vuelvo a leer el javadoc, setVisible validará la ventana si aún no se puede visualizar. Por lo tanto, no necesitará una llamada explícita para revalidate . setSize invalidará el componente pero no lo volverá a validar .

TL; DR: Vale la pena leer sobre cómo funcionan la validación y la capacidad de visualización en Swing para que no cometas los errores que acabo de cometer.

Llame a setVisible solo después de haber creado la interfaz de usuario …

 public void run() { frame = new JFrame("Simple Adventure"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(576, 576); // frame.setResizable(false); getImage(); c = frame.getContentPane(); cards = new CardLayout(); c.setLayout(cards); gamepanel = new DrawPanel1(); gamepanel.setBackground(Color.black); c.add(gamepanel, "Panel 1"); // Lucky last... frame.setVisible(true); } 

De lo contrario, deberá volver a validar el marco