Java does not fire repaint()

Good afternoon. There is an image, and the methods paintComponent (Graphics g) and repaint (). So: the image is drawn only if you manually change the window size with the mouse, and I want that immediately. The idea is to put repaint() in the constructor, but it doesn't work( The structure of the program: the main class MainWindow extends JFrame, from it the class GameField extends JPanel is created, and in this GameField the methods paintComponent(Graphics g) and repaint () are created. The image is drawn inside the paintComponent method.

package com.company;
import javax.swing.*;
public class MainWindow extends JFrame {
    public  static  final double VERSION = 0.1;

    public MainWindow() {
        setTitle("... " + VERSION);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(1024, 768);
        setVisible(true);
        setLocation(400,100);
        add(new GameField()); // it extends JPanel
    }

    public static void main(String[] args) {
        MainWindow mainWindow = new MainWindow();
    }
}

GameField Class:

package com.company;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class GameField extends JPanel implements ActionListener {

    private final int SPEED = 5;
    private int shipX, shipY;
    private int asteroidX, asteroidY;
    private Image ship;
    private Image asteroid;
    private Image shot;

    public GameField(){
        setBackground(Color.black);
        loadImages();
        repaint();
    }

    public void loadImages(){
        ImageIcon shipIcon = new ImageIcon("ship.png");
        ship = shipIcon.getImage();
    }

    @Override  
    public void paintComponent(Graphics g) { 
        super.paintComponent(g);
        g.drawImage(ship,500, 500, this); 
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        repaint();
    }

}
Author: Dmitry, 2017-08-20

1 answers

The setVisible(true) method of JFrame should be called last. In your case, you first force the frame to render, and only then fill it with content, it should be the opposite.

public MainWindow() {
    setTitle("... " + VERSION);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(1024, 768);
    setLocation(400,100);
    add(new GameField());
    setVisible(true);
}
 2
Author: Shockoway, 2017-08-20 12:01:10