0

I am creating a Blackjack game and need to refresh the JFrame every time the user clicks a button. However, the frame is not updating! I've tried for hours trying to fix this in vain.

How do I properly reload all the elements in the frame based on the Stack of ImageIcon objects I use to load images?

Here is my code:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Stack;

public class Blackjack extends JFrame implements ActionListener {
    public void drawGUI(boolean firstTime) {
        getContentPane().removeAll();

        setLayout(new GridLayout(3, 9, 1, 1));
        updateValues();

        add(new JLabel(DEALER_TEXT, SwingConstants.CENTER));
        add(new JLabel("Value: " + computerValue, SwingConstants.CENTER));
        for(int i = 0; i < computerCards.size(); i++)
            add(new JLabel(computerCards.get(i).getImagePath()));

        leaveSpacing(false);

        add(new JLabel(USER_TEXT, SwingConstants.CENTER));
        add(new JLabel("Value: " + userValue, SwingConstants.CENTER));
        for(int i = 0; i < userCards.size(); i++)
            add(new JLabel(userCards.get(i).getImagePath()));

        leaveSpacing(true);

        if(firstTime) {
            hitButton.addActionListener(this);
            standButton.addActionListener(this);
        }

        leaveSpacing(3);
        add(hitButton);
        add(standButton);
        leaveSpacing(1);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 1
    TL; DR; Before you go insane, why don't you post [mcve] to make it easier for you to pin-point the problem and get help ? – c0der Apr 22 '17 at 08:52
  • @c0der Thanks for your reply. The problem is updating. In the method actionPerformed(ActionEvent evt), it calls drawGUI(boolean firstTime) to redraw the entire JFrame; but it doesn't remove all the elements and update them. It just keeps the elements the same. – Imagine Dragons Apr 22 '17 at 08:55
  • 1
    I understand that. I assume the problem can be demonstrated with much shorter code. [mcve] also means compilable – c0der Apr 22 '17 at 09:00

2 Answers2

2

You need to call revalidate(); and repaint(); at the end of your drawGUI(); method. This should do the trick.

This is answered before on SO however, see: Java Swing revalidate and repaint

Community
  • 1
  • 1
skubski
  • 1,586
  • 2
  • 19
  • 25
  • You've saved me countless hours. Thanks! – Imagine Dragons Apr 22 '17 at 09:15
  • How come this must be done at the end of the method? Why not before? – Imagine Dragons Apr 22 '17 at 09:17
  • Actually, you need to `revalidate`, after you did a `removeAll` to notify Swing a panel is so called "dirty", and you need to call `repaint` after you readded a component to let the layout manager recalculate the layout again. So it doesn't really need to be at the end. – skubski Apr 22 '17 at 09:25
2

How about this a (working) mcve :

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;

public class BalckJack extends JFrame implements ActionListener {

    private JButton hitButton = new JButton("Hit");
    private int computerValue;

    public static void main(String[] args) {

        BalckJack frame = new BalckJack();
        frame.setTitle("Cards");
        frame.setSize(800, 320);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public BalckJack() {

        computerValue = 0;

        for(int i = 0; i < 27; i++) {
            add(new JLabel(new ImageIcon("")));
        }

        drawGUI(true);
    }

    public void drawGUI(boolean firstTime) {

        getContentPane().removeAll();

        setLayout(new GridLayout(1, 2, 1, 1));

        add(new JLabel("Value: " + computerValue++, SwingConstants.CENTER));

        if(firstTime) {
            hitButton.addActionListener(this);
        }

        add(hitButton);
        revalidate();  //(!!!!)
    }

    @Override
    public void actionPerformed(ActionEvent evt) {

        drawGUI(false);
    }
}
c0der
  • 18,467
  • 6
  • 33
  • 65