Problemas de renderização de componentes

Opa, fala aí, tudo bem? Venho aqui pedir uma solução para o meu código.
O problema é o seguinte: todo componente que eu crio está ficando por debaixo dos meus frames e eu já tentei de tudo pra tentar jogar eles para cima. Como faço para deixá-los em cima com esse loop? Estou usando o framework do netbeans Form JFrame para facilitar a minha criação.

public class FrmGame extends javax.swing.JFrame implements Runnable{
private boolean running = false;
private Thread thread;

/**
 * Constructor.
 */
public FrmGame() {
    setNimbusLookAndFeel();
    initComponents();
    this.start();
    
}


/**
 * Game loop.
 */
@Override
public void run(){
    long lastTime = System.nanoTime();
    double amountOfTicks = 60.0;
    double ns = 1000000000 / amountOfTicks;
    double delta = 0;
    long timer = System.currentTimeMillis();
    int frames = 0;
    while(running){
        long now = System.nanoTime();
        delta += (now - lastTime) / ns;
        lastTime = now;
        while(delta >=1){
                update();
                delta--;
                }
        if(running){
            render();
        }
        frames++;

        if(System.currentTimeMillis() - timer > 1000){
                
            timer += 1000;
            System.out.println("FPS: "+ frames);
                    frames = 0;
        }
    }
    stop();
}

/**
 * Starts the thread.
 */
public void start(){
    setVisible(true);
    thread = new Thread(this);
    running = true;
    thread.start();
}

/**
 * Stops the thread.
 */
public void stop(){
    try {
        thread.join();
        running = false;
    } catch (InterruptedException ex) {
        throw new RuntimeException(ex);
    }
}

/**
 * Updates whatever object that needs to be updated.
 */
public void update(){
    
}

/**
 * Renders whatever object that needs to be rendered.
 */
 public void render(){
    BufferStrategy bs = getBufferStrategy();
     if (bs == null) {
         createBufferStrategy(3);
         return;
     }
    
    Graphics g = bs.getDrawGraphics();
    //g.drawImage(new ImageIcon(getClass().getResource("main.jpg")).getImage(), 3, 26, this);
    
    
    
    
    g.dispose();
    bs.show();
}
 
 

@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jButton1 = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle(GameConstants.GAME_TITLE);
    setMaximumSize(new Dimension(GameConstants.GAME_WIDTH, GameConstants.GAME_HEIGHT));
    setMinimumSize(new Dimension(GameConstants.GAME_WIDTH, GameConstants.GAME_HEIGHT));
    setPreferredSize(new Dimension(GameConstants.GAME_WIDTH, GameConstants.GAME_HEIGHT));
    setResizable(false);
    getContentPane().setLayout(null);

    jButton1.setText("jButton1");
    getContentPane().add(jButton1);
    jButton1.setBounds(10, 0, 73, 23);

    pack();
    setLocationRelativeTo(null);
}// </editor-fold>                        


private void setNimbusLookAndFeel(){
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(FrmGame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
}


public static void main (String args[]){
    new FrmGame();
}


// Variables declaration - do not modify                     
private javax.swing.JButton jButton1;
// End of variables declaration                   

}

O problema está no seu método render você está repintando toda a área do Frame, com isso seu Graphics é pintado por cima dos componentes adicionados.
Após ter pintado/desenhado as imagens de seu jogo, chame o método paintComponents para pintar os componentes no seu objeto Graphics.

 public void render() {
    BufferStrategy bs = getBufferStrategy();
    if (bs == null) {
        createBufferStrategy(3);
        return;
    }

    Graphics g = bs.getDrawGraphics();
    // g.drawImage(new ImageIcon(getClass().getResource("main.jpg")).getImage(), 3, 26, this);

    // quando terminou de pintar o que precisava, repinta os componentes neste objeto Graphics
    paintComponents(g);

    g.dispose();
    bs.show();
}
2 curtidas

Opa, staroski, obrigado por responder! Fiz tudo o que você me indicou, e realmente faz todo o sentido. Porém, agora que a classe está pintando os componentes por último, tudo o que foi pintado antes desaparece. Eu tentei reescrever o método paintComponent e usá-lo para renderizar meus objetos, porém acontece a mesma coisa. Os componentes ou ficam por baixo, ou ficam por cima e cobrem tudo o que eu renderizei, e não só a parte que eles cobrem. E é isso que eu acho estranho. Não deveriam cobrir apenas os seus bounds? Enfim, segue o código modificado.

public void render(){
    BufferStrategy bs = getBufferStrategy();
    if (bs == null) {
        createBufferStrategy( 3 );
        return;
    }
    
    Graphics g = bs.getDrawGraphics();
    /* Render anything below  */
    
    
    /* DO NOT render anything below */
    paintComponents(g);
    g.dispose();
    bs.show();
}

@Override
public void paintComponents(Graphics g){
    super.paintComponents(g);
    
    g.setColor(Color.red);
    g.fillRect(0, 0, 200, 200);
}

Se eu boto o super.paintComponents(g) para cima, os componentes ficam pra baixo. Agora, se eu boto no final do código, ele simplesmente cobre o retângulo. Eu tenho apenas uma JLabel de teste que está no meio do rect vermelho, não é possível que o tamanho da label seja maior do que o rect.

1 curtida

Qual o motivo de você sobrescrever o método paintComponents?
É só pra invocar ele, não sobrescrever.

1 curtida

Foi apenas uma tentativa de driblar o problema que está dando. O que eu quero é: Um componente em cima de um retângulo. Quando eu chamo o método painComponent no final, o meu retângulo desaparece, e quando eu chamo o paintComponent no começo, o retângulo fica em cima do meu componente.

public void render(){
    BufferStrategy bs = getBufferStrategy();
    if (bs == null) {
        createBufferStrategy( 3 );
        return;
    }
    
    Graphics g = bs.getDrawGraphics();
    /* Render anything below  */
    
    g.setColor(Color.red);
    g.fillRect(0, 0, 200, 200);
    
    /* DO NOT render anything below */
    paintComponents(g);
    g.dispose();
    bs.show();
}