You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过ActionListener实现点击切换不重复的骰子图片?

问题描述

创建简易骰子GUI,要求点击按钮时显示随机骰子值图片,且不会连续出现相同值。目前已在ActionListener中编写代码,但点击后图片未切换。defineBtn方法中lblNewLabel.setIcon(dice[verifiedNum])本应实现图片切换,却出现编译错误:

Exception in thread "AWT-EventQueue-0" java.lang.Error: Unresolved compilation problem: lblNewLabel cannot be resolved

尝试将该行代码放入diceLbl方法中,图片仍无法切换,请问需要做哪些修改才能让JLabel随机切换图片且不重复?

原代码如下:

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;
    }

    
}
解决方案
  • 提升JLabel为类成员变量:原代码中lblNewLabel是构造方法内的局部变量,defineBtn方法的ActionListener无法访问它。把lblNewLabel声明为类的成员变量,让ActionListener可以直接调用。
  • 修正初始值匹配:初始化lastRolledNum时,要和初始生成的骰子值保持一致,避免第一次点击时因为新随机数和初始值相同导致do-while死循环。
  • 简化随机数生成逻辑:确保每次生成的随机数与上一次不同,逻辑保持简洁。

修改后的完整代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

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

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();
    
    // 提升为类成员变量
    JLabel lblNewLabel;
    int lastRolledNum;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        SwingUtilities.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);
        
        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) { 
                int newRoll;
                do {
                    newRoll = rand.nextInt(6);
                } while (newRoll == lastRolledNum);
                
                lastRolledNum = newRoll;
                lblNewLabel.setIcon(dice[lastRolledNum]);
            }
        });
        return btnNewButton;
    }

    private JLabel diceLbl() {
        JLabel label = new JLabel("");
        label.setOpaque(true);
        label.setBackground(new Color(192, 192, 192));
        label.setHorizontalAlignment(SwingConstants.CENTER);
        
        // 初始化第一次的骰子值
        lastRolledNum = rand.nextInt(6);
        label.setIcon(dice[lastRolledNum]);
        
        return label;
    }
}

内容的提问来源于stack exchange,提问作者HalfokayCS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:55:05