Search code examples
javaswingjpaneljbutton

JLabel is not visible when JButton is clicked whilst JPanel is loading


When I click background selector on my main panel, it takes a while to load the JPanel and I wanted to show a loading JLabel whilst the background selector panel is loading, then disappear when the panel finally shows up. I tried to implement this in my buttons action listener. But for some reason when I remove the backgroundPanel() method from the action listener (aka panel is not being loaded when JButton is clicked but rather just the JLabel showing up), the label shows up when the button is clicked, but normally the label does not appear. I cannot understand why.

Window class:

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;

/**
 *
 */
public class Window {

public static JFrame frame;
GameWindow game;
BackgroundSelector background;
static DifficultySelector difficulty;
public static MainBackgroundImage main; // start window
JProgressBar progressBar = new JProgressBar();
private boolean loaded = false;

public Window() throws IOException {

    frame = new JFrame("Brick Builder Game"); // creates JFrame

    game = new GameWindow(); // creates new GAME window
    main = new MainBackgroundImage(); // creates MAIN screen
    background = new BackgroundSelector(); // creates BACKGROUND SELECTOR window
    difficulty = new DifficultySelector(); // creates DIFFICULTY SELECTOR window

    main.setLayout(null);

    frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
    frame.setSize(500,500);
    frame.setVisible(true);
    frame.setResizable(false);

    frame.getContentPane().add(main); // adds MAIN screen to frame


    JButton start = new JButton();
    Image startImg = ImageIO.read(getClass().getResource("start.png"));
    start.setIcon(new ImageIcon(startImg));
    start.setBounds(150,270,200,40);
    start.setOpaque(false);
    start.setBorderPainted(false);

    JButton backgroundSelector = new JButton();
    Image selectorImg = ImageIO.read(getClass().getResource("selector.png"));
    backgroundSelector.setIcon(new ImageIcon(selectorImg));
    backgroundSelector.setBounds(150, 320,200,40);
    backgroundSelector.setOpaque(false);
    backgroundSelector.setBorderPainted(false);


    JButton quit = new JButton();
    Image quitImg = ImageIO.read(getClass().getResource("quit.png"));
    quit.setIcon(new ImageIcon(quitImg));
    quit.setBounds(150,370,200,40);
    quit.setOpaque(false);
    quit.setBorderPainted(false);

    JLabel loading = new JLabel();
    loading.setBounds(150,400,100,20);

    main.repaint();

    start.setBackground(Color.white);
    backgroundSelector.setBackground(Color.white);
    quit.setBackground(Color.white);

    start.setFocusable(false);
    quit.setFocusable(false);
    backgroundSelector.setFocusable(false);
    start.setAlignmentX(Component.CENTER_ALIGNMENT);
    quit.setAlignmentX(Component.CENTER_ALIGNMENT);
    backgroundSelector.setAlignmentX(Component.CENTER_ALIGNMENT);
    
    main.add(start); // adds JButton
    main.add(quit);
    main.add(backgroundSelector);
    main.add(loading);
    main.add(progressBar);

    start.addActionListener(e -> difficultyPanel());

    quit.addActionListener(e -> {
        frame.dispose();
    });

    backgroundSelector.addActionListener(e -> {
        loading.setText("Loading...");
        backgroundPanel();
    });

    //backgroundSelector.addActionListener(e -> backgroundPanel());
}

public static void mainPanel(){
    frame.getContentPane().removeAll();
    frame.getContentPane().add(main);
    frame.validate();
}

public void backgroundPanel(){
    //loaded = false;
    frame.getContentPane().removeAll();
    background = new BackgroundSelector();
    frame.getContentPane().add(background);
    frame.revalidate();
}

public void difficultyPanel(){
    frame.getContentPane().removeAll();
    difficulty = new DifficultySelector();
    frame.getContentPane().add(difficulty);
    frame.requestFocusInWindow();
    frame.revalidate();
}

    public static void main (String[]args) throws IOException {
        new Window();
    }
}

Background selector class:

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyListener;

/**
 * This class creates the background selector JPanel which allows the player to choose a background
 * of their choice. A choice of 6 backgrounds is given to the player to choose from.
 *
 */
public class BackgroundSelector extends JPanel{

    DifficultySelector difficulty = new DifficultySelector();

    private final ClassLoader cl = Thread.currentThread().getContextClassLoader();
    private final Image image = Toolkit.getDefaultToolkit().getImage(cl.getResource("black.jpg"));

    JLabel label;

    // creates the radioButtons which display the backgrounds to choose from
    JRadioButton radioButton;
    JRadioButton radioButton2;
    JRadioButton radioButton3;
    JRadioButton radioButton4;
    JRadioButton radioButton5;
    JRadioButton radioButton6;

    public static boolean option1 = false;
    public static boolean option2 = false;
    public static boolean option3 = false;
    public static boolean option4 = false;
    public static boolean option5 = false;
    public static boolean option6 = false;

    /**
 * Constructor which adds the radio buttons to a button group and displays them on the JPanel using a flow layout.
 *
 */
public BackgroundSelector(){

    label = new JLabel("Please select a background", JLabel.CENTER);
    label.setFont(new Font("Verdana", Font.BOLD, 18));
    label.setForeground(Color.white);

    setLayout(new FlowLayout());
    ButtonGroup group = new ButtonGroup();
    group.add(radioButton);
    group.add(radioButton2);
    group.add(radioButton3);
    group.add(radioButton4);
    group.add(radioButton5);
    group.add(radioButton6);

    option1();
    option2();
    option3();
    option4();
    option5();
    option6();
    add(label);
}


/**
 * Paints background image of panel to black chalk image.
 * @param g
 */
@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    image.getScaledInstance(500, 500,Image.SCALE_SMOOTH);
    while(!prepareImage(image, this)) {
        prepareImage(image, this);
    }
    g.drawImage(image,0,0,null);
}

/**
 * Converts the url to an image which will be used as the icon for the JRadioButton.
 *
 * @param url The url of the image.
 * @return The image with a specific height and width.
 */
public String URL(String url){
    return "<html><body><img src='" + url + "'width=128 height=128>";
}

/**
 * Adds radioButton to the JPanel, when clicked, creates a new game with the space background.
 *
 */
public void option1() {
    String url = URL("https://www.nasa.gov/sites/default/files/styles/full_width/public/thumbnails/image/main_image_star-forming_region_carina_nircam_final-1280.jpg");
    radioButton = new JRadioButton(url);
    add(radioButton);
    radioButton.addActionListener(e -> {
        Window.frame.getContentPane().removeAll();
        //game.changeFilepath("space.jpg");
        Window.frame.getContentPane().add(difficulty);
        Window.frame.requestFocusInWindow();
        Window.frame.revalidate();
        option1 = true;
    });
}

/**
 * Adds radioButton to the JPanel, when clicked, creates a new game with the bricks background.
 *
 */
public void option2(){
    String url = URL("https://appgrooves.com/cdn/mc/GAME_ARCADE/7_w1200.jpg");
    radioButton2 = new JRadioButton(url);
    add(radioButton2);
    radioButton2.addActionListener(e -> {
        Window.frame.getContentPane().removeAll();
        //game.changeFilepath("space.jpg");
        Window.frame.getContentPane().add(difficulty);
        Window.frame.requestFocusInWindow();
        Window.frame.revalidate();
        option2 = true;
    });
}

/**
 * Adds radioButton to the JPanel, when clicked, creates a new game with the stars background.
 *
 */
public void option3(){
    String url = URL("https://upload.wikimedia.org/wikipedia/commons/2/26/Oldest_star_in_solar_neighbourhood.jpg");
    radioButton3 = new JRadioButton(url);
    add(radioButton3);
    radioButton3.addActionListener(e -> {
        Window.frame.getContentPane().removeAll();
        //game.changeFilepath("stars.jpg");
        Window.frame.getContentPane().add(difficulty);
        Window.frame.requestFocusInWindow();
        Window.frame.revalidate();
        option3 = true;
    });
}

/**
 * Adds radioButton to the JPanel, when clicked, creates a new game with the bubbles background.
 *
 */
public void option4(){
    String url = URL("https://cdn.pocket-lint.com/assets/images/131835-phones-news-feature-cropped-best-iphone-wallpapers-image72-7pqcs1gy9h.jpg");
    radioButton4 = new JRadioButton(url);
    add(radioButton4);
    radioButton4.addActionListener(e -> {
        Window.frame.getContentPane().removeAll();
        //game.changeFilepath("stars.jpg");
        Window.frame.getContentPane().add(difficulty);
        Window.frame.requestFocusInWindow();
        Window.frame.revalidate();
        option4 = true;
    });
}

/**
 * Adds radioButton to the JPanel, when clicked, creates a new game with the forest background.
 *
 */
public void option5(){
    String url = URL("https://images.hdqwalls.com/download/blue-forest-minimal-4k-kz-2048x2048.jpg");
    radioButton5 = new JRadioButton(url);
    add(radioButton5);
    radioButton5.addActionListener(e -> {
        Window.frame.getContentPane().removeAll();
        //game.changeFilepath("stars.jpg");
        Window.frame.getContentPane().add(difficulty);
        Window.frame.requestFocusInWindow();
        Window.frame.revalidate();
        option5 = true;
    });
}

/**
 * Adds radioButton to the JPanel, when clicked, creates a new game with the japanese purple background.
 *
 */
public void option6(){
    String url = URL("https://www.pixelstalk.net/wp-content/uploads/images5/Cool-Japanese-Backgrounds-HD-Free-download.jpg");
    radioButton6 = new JRadioButton(url);
    add(radioButton6);
    radioButton6.addActionListener(e -> {
        Window.frame.getContentPane().removeAll();
        //game.changeFilepath("stars.jpg");
        Window.frame.getContentPane().add(difficulty);
        Window.frame.requestFocusInWindow();
        Window.frame.revalidate();
        option6 = true;
    });
}

}


Solution

  • Just add the following method to the background selector :) and call it on background() method in window

    public void resetLayout() {
        radioButton.setSelected(false);
        radioButton2.setSelected(false);
        radioButton3.setSelected(false);
        radioButton4.setSelected(false);
        radioButton5.setSelected(false);
        radioButton6.setSelected(false);
    }
    

    really ugly, could be better, but works!