Search code examples
javauser-interfacewindowbuilderdice

JLabel and JPanel - Dynamically using a GUI to display different images


I'm going to post this again and try to be more precise and succinct this time around. I have installed WindowBuilder and have been using that to generate my GUI code.

So I have my GUI set up and everything going. WindowBuilder automatically makes a method called initialize() and that's where all my GUI code is.

I have redacted a lot of my code. I think I have left everything needed to identify what it is I'm trying to do.

I'm not sure if the code below works, being redacted and all, but in general, whenever the user clicks the "ROLL" button on the GUI, it should execute the rollDice() method, which cycles a side of a dice for .1 second each, and finally stopping and landing on the final value.

I have been trying like crazy to implement a method to do this, but anything and everything I make regarding to the GUI outside of the initialize() class does not work at all - yet returns no errors in my code. Any help would be appreciated!

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Font;
import java.awt.Image;
import java.awt.Label;

import javax.swing.JScrollPane;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
import java.util.*;
import javax.swing.JComboBox;
import java.awt.Color;
import javax.swing.SwingConstants;

public class PigDice {
public JFrame frame;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                PigDice window = new PigDice();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}//Main Method

static void diceTumble(){

}

static void pausee(int x){
    try {
        Thread.sleep(x);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}//endsPause

/**
 * Create the application.
 */
public PigDice() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {

    frame = new JFrame();
    frame.setBounds(100, 100, 1038, 892);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(null);

    JPanel panel = new JPanel();
    panel.setBounds(0, 0, 1016, 830);
    frame.getContentPane().add(panel);
    panel.setLayout(null);

    JButton btnRoll = new JButton("Roll");
    btnRoll.setFont(new Font("Tahoma", Font.BOLD, 24));
    btnRoll.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            tumbleDice();
        }
    });
    btnRoll.setBounds(292, 639, 135, 52);
    panel.add(btnRoll);

}

static void tumbleDice(){
    for(int i = 0; i < 25; i++){
        sleep(100);

        JPanel panel_1 = new JPanel();//panel for dice1
        panel_1.setBounds(277, 393, 150, 150);
        panel.add(panel_1);
        panel_1.setLayout(null);

        JPanel panel_2 = new JPanel();//panel for dice2
        panel_2.setBounds(564, 393, 150, 150);
        panel.add(panel_2);
        panel_2.setLayout(null);

        JLabel dice1 = new JLabel("dice1");
        dice1.setHorizontalAlignment(SwingConstants.CENTER);
        dice1.setBounds(0, 0, 150, 150);
        Image die1 = new ImageIcon(this.getClass().getResource("" + tumble())).getImage();
        dice1.setIcon(new ImageIcon(die1));
        panel_1.add(dice1);

        JLabel dice2 = new JLabel("dice2");
        dice2.setHorizontalAlignment(SwingConstants.CENTER);
        dice2.setBounds(0, 0, 150, 150);
        Image die2 = new ImageIcon(this.getClass().getResource("" + tumble())).getImage();
        dice2.setIcon(new ImageIcon(die2));
        panel_2.add(dice2); 
    }//for loop
}//tumbleDice method

String tumble(){
    int random = (int) (Math.random() * 6) + 1;
    if(random == 1)
        return "/side1.png";
    if(random == 2)
        return "/side2.png";
    if(random == 3)
        return "/side3.png";
    if(random == 4)
        return "/side4.png";
    if(random == 5)
        return "/side5.png";
    return "/side6.png";
}
}//end PigDice 

Solution

    1. Don't keep creating new components. If you want to change the image, then just use the setIcon() method of the JLabel.

    2. Don't use a null layout. Swing was designed to be used with layout managers.

    3. Don't use Thread.sleep(). This causes the Event Dispatch Thread to sleep which means the GUI can't repaint itself. Instead use a Swing Timer.

    The Swing Tutorial has examples of all these suggestions so read the tutorial for the basics.

    Also, don't continually read the image files. This is not very efficient if you are going to loop 25 times. Instead the images should be loaded in the constructor of your class. Then maybe store them in an ArrayList and just return the random index of the Icon you want to display in the label.