I am trying to create a simple dice GUI where a random image of a dice value will appear on click, without the same value appearing twice in a row. I am to the point where I need to define the code in the actionListener, but upon clicking, the images do not change. The line of code that should cause the images to change is lblNewLabel.setIcon(dice[verifiedNum])
in the defineBtn
method but I get the error that it cannot be resolved to a type. My question is: what changes do I need to make in order to get the JLabel to change images randomly without repeating the same image? The error I get is Exception in thread "AWT-EventQueue-0" java.lang.Error: Unresolved compilation problem:
lblNewLabel cannot be resolved.
public class LabGuiDice extends JFrame {
final ImageIcon image1 = new ImageIcon(LabGuiDice.class.getResource("/guiDice/img/die-1.png"));
final ImageIcon image2 = new ImageIcon(LabGuiDice.class.getResource("/guiDice/img/die-2.png"));
final ImageIcon image3 = new ImageIcon(LabGuiDice.class.getResource("/guiDice/img/die-3.png"));
final ImageIcon image4 = new ImageIcon(LabGuiDice.class.getResource("/guiDice/img/die-4.png"));
final ImageIcon image5 = new ImageIcon(LabGuiDice.class.getResource("/guiDice/img/die-5.png"));
final ImageIcon image6 = new ImageIcon(LabGuiDice.class.getResource("/guiDice/img/die-6.png"));
final JPanel contentPane;
final ImageIcon[] dice = { image1, image2, image3, image4, image5, image6 };
final Random rand = new Random();
int randNum = rand.nextInt(6);
int verifiedNum = 0;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
LabGuiDice frame = new LabGuiDice();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public LabGuiDice() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout(0, 0));
JButton btnNewButton = defineBtn();
contentPane.add(btnNewButton, BorderLayout.SOUTH);
JLabel lblNewLabel = diceLbl();
contentPane.add(lblNewLabel, BorderLayout.CENTER);
}
private JButton defineBtn() {
JButton btnNewButton = new JButton("Roll 'Em");
btnNewButton.setAlignmentX(Component.CENTER_ALIGNMENT);
btnNewButton.setAlignmentY(Component.TOP_ALIGNMENT);
btnNewButton.setFont(new Font("Javanese Text", Font.PLAIN, 15));
btnNewButton.setBackground(new Color(178, 172, 136));
btnNewButton.setForeground(new Color(255, 255, 255));
btnNewButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {
do{randNum = rand.nextInt(6);}
while (randNum == verifiedNum);
verifiedNum = randNum;
lblNewLabel.setIcon(dice[verifiedNum]);
}});
return btnNewButton;
}
private JLabel diceLbl() {
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setOpaque(true);
lblNewLabel.setBackground(new Color(192, 192, 192));
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
lblNewLabel.setIcon(dice[randNum]);
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
return lblNewLabel;
}
}
When I tried to place lblNewLabel.setIcon(dice[verifiedNum])
inside of the diceLbl
method the image still does not change upon click.
You have...
private JLabel diceLbl() {
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setOpaque(true);
lblNewLabel.setBackground(new Color(192, 192, 192));
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
lblNewLabel.setIcon(dice[randNum]);
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
return lblNewLabel;
}
which is interesting, but each time it's called, it will create a new instance of JLabel
.
Then in the constructor, you have...
JLabel lblNewLabel = diceLbl();
contentPane.add(lblNewLabel, BorderLayout.CENTER);
which defines a local variable lblNewLabel
which adds (the newly created instance) to the frame.
But, lblNewLabel
is undefined within the context of your ActionListener
.
Start by creating a instance variable (below the definition of verifiedNum
)
private JLabel lblNewLabel;
Then modify the diceLbl
method to only every create a single instance of the JLabel
, something like...
private JLabel diceLbl() {
if (lblNewLabel == null) {
lblNewLabel = new JLabel("");
lblNewLabel.setOpaque(true);
lblNewLabel.setBackground(new Color(192, 192, 192));
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
lblNewLabel.setIcon(dice[randNum]);
lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
}
return lblNewLabel;
}
Then, in your ActionListener
you can simply do...
diceLbl().setIcon(dice[verifiedNum]);