我的 JButton 的 ActionListener 如何访问另一个类中的变量?

2022-01-24 00:00:00 java swing actionlistener jbutton jframe

我正在为一个项目做老虎机.我无法让我的 JButton 从我的 ArrayList 生成新的随机数.我可以在程序启动并设置 actionlistener 时随机化数字,但它不能满足我的需要.这只是为了测试目的.

I am doing a slot machine for a project. I am having trouble getting my JButton to generate new random numbers from my ArrayList. I can randomize the numbers when the program starts and have an actionlistener set up, but it doesn't do what I need. It was merely for testing purposes.

我的 Actionlistener 位于不同的 Java 文件中.一切正常,我只是不知道如何在 plc1plc2plc3 的占位符中生成新的随机数点击.

My Actionlistener is in a different Java file. Everything works, I just can't figure out how to generate new randoms in the placeholder of plc1, plc2, and plc3 when the button is clicked.

我最近才开始真正编写代码,大约在 3 周前.请不要仇恨,这是我的第一个项目.

package GGCGuiLotto;

import java.util.ArrayList;
import java.awt.Color;
import java.awt.Image;
import java.awt.BorderLayout; 
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Icon;
import javax.swing.JOptionPane;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;

import java.util.Random;


public class GGCGuiLotto {

public static void main(String[] args) {    

//Arraylist of images

ImageIcon pic0 = new ImageIcon("pics/pic1.png");
ImageIcon pic1 = new ImageIcon("pics/pic2.png");
ImageIcon pic2 = new ImageIcon("pics/pic3.png");
ImageIcon pic3 = new ImageIcon("pics/pic4.png");
ImageIcon pic4 = new ImageIcon("pics/pic5.png");
ImageIcon pic5 = new ImageIcon("pics/pic6.png");
ImageIcon pic6 = new ImageIcon("pics/pic7.png");

final ArrayList<ImageIcon> slotlist = new ArrayList<ImageIcon>();   
    slotlist.add(pic0);
    slotlist.add(pic1);
    slotlist.add(pic2);
    slotlist.add(pic3);
    slotlist.add(pic4);
    slotlist.add(pic5);
    slotlist.add(pic6);

    Random ran = new Random();

    int plc1 = ran.nextInt(4);
    int plc2 = ran.nextInt(4);
    int plc3 = ran.nextInt(4);

    //generates the frame and the labels are added.

    JFrame frame = new JFrame();
    frame.setSize (400,275);
    frame.setTitle("GGC Lotto Slots Rcorbin");
    frame.setResizable(false);
    frame.setVisible(true);

    JPanel pnlReels = new JPanel();
    frame.add(pnlReels);

    JPanel aReel1 = new JPanel();
    aReel1.setBackground(new Color(25,25,112));
    aReel1.setBounds(15,10,100,100);

    JPanel bReel2 = new JPanel();
    bReel2.setBackground(new Color(25,25,112));
    bReel2.setBounds(145,10,100,100);

    JPanel cReel3 = new JPanel();
    cReel3.setBackground(new Color(25,25,112));
    cReel3.setBounds(275,10,100,100);   

        pnlReels.add(aReel1);
    pnlReels.add(bReel2);
    pnlReels.add(cReel3);   

    JLabel aReel1lbl = new JLabel();
    JLabel bReel2lbl = new JLabel();
    JLabel cReel3lbl = new JLabel();

    aReel1.add(aReel1lbl);
    bReel2.add(bReel2lbl);
    cReel3.add(cReel3lbl);  

    aReel1lbl.setIcon(slotlist.get(plc1));
    bReel2lbl.setIcon(slotlist.get(plc2));
    cReel3lbl.setIcon(slotlist.get(plc3));  

    //jbutton 
    JButton slotbtn1 = new JButton();
    slotbtn1.setText("GGC LOTTO Click ME");
    pnlReels.add(slotbtn1);
    slotbtn1.setBounds(145,50,100,75);
    //FirstGuiListener act = new FirstGuiListener();
    //slotbtn1.addActionListener((ActionListener) act); 

GenPLCListener genPLC = new GenPLCListener();
slotbtn1.addActionListener((genPLC));
    {}
    if (plc1 == plc2 && plc1 == plc3 && plc2 == plc3)
    {
        JOptionPane.showConfirmDialog(null,"Winner! Play Again? ","GGC Lotto Slots RCorbin ",JOptionPane.YES_NO_OPTION);
        //System.out.println("Winner");
    }
    else
    {
        //JOptionPane.showMessageDialog(null,"No Winner Winner Chicken Dinner ! ");
        System.out.println("Crazy");    }

}
}

<小时>

package GGCGuiLotto;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JOptionPane;

class GenPLCListener extends GGCGuiLotto implements ActionListener{
public void actionPerformed(ActionEvent event){
        System.out.println("Works");

JOptionPane.showConfirmDialog(null,"Choose Wisely. ","Click If you Trust!",JOptionPane.YES_NO_OPTION);
}
}

推荐答案

尝试 extends GCGGuLotto 不会做你认为应该做的事情,这让你可以访问 相同实例变量.所以摆脱它.相反,您可以通过引用,将 GGCGuiLotto 的当前实例传递给您的听众.并且有一些 getter 和 setter 可以从 GGCGuiLotto 类中访问您需要的变量.我的意思可能是这样的(不完全确定你想要完成什么,所以这只是一个例子).

Trying to extends GGCGuiLotto isn't going to do what you think it's supposed to, which is give you access to the same instance variables. So get rid of that. Instead you can pass-by-reference, the current instance of GGCGuiLotto to your listener. And have some getters and setters to access the variables you need from the GGCGuiLotto class. What I mean is maybe something like this (not completely sure what you're trying to accomplish, so this is just an example).

public class GenPLCListener implements ActionListener {
    private GGCGuiLotto lotto;

    public GenPLCListener(GGCGuiLotto lotto) {
        this.lotto = lotto;
    }

    @Override
    public void actionPerfomred(ActionEvent e) {
        List<ImageIcon> slotList = lotto.getSlotList();
        Collections.shuffle(slotList);  // shuffle the list
        // do something else if need be.
    }
}

创建侦听器时,将 this 传递给它.thisGCGGuLotto

When you create the listener, pass this to it. this being the instance of GGCGuiLotto

一些旁注

  • Swing 程序与控制台程序不同.您不想在 main 方法中执行所有操作.对于初学者,您的 main 方法中的代码,您可以将其放入构造函数中.然后在 main 方法中创建一个 GGCGuiLotto 的实例.

  • Swing programs aren't like console programs. You don't want to do everything inside your main method. For starters, the code in your main method, you could put in the constructor instead. Then create an instance of GGCGuiLotto in the main method.

Swing 应用程序应在事件调度线程上运行.请参阅初始线程

Swing apps should be run on the Event Dispatch Thread. See Initial Threads

也许对您的问题更合适的解决方案是拥有一个带有 pullSlot 方法的 interface,您可以在 GGCGuiLotto 类中覆盖该方法只需将 interface 传递给侦听器并在 actionPerformed 中调用 pullSlot 方法.像这样的

Maybe a more proper solution to your problem would be to have an interface with the pullSlot method that you can override in the GGCGuiLotto class and just pass the interface to the listener and call the pullSlot method inf your actionPerformed. Something like this

public interface PullInterface {
    public void pullSlot();
}

public class GGCGuiLotto implements PullInterface {
    ArrayList<ImageIcon> slotList = new ArrayList<>();  // global scope.
    JLabel aReel1lbl = new JLabel();
    JLabel bReel2lbl = new JLabel();
    JLabel cReel3lbl = new JLabel();
    Random rand = new Random();

    public GGCGuiLotto() {
        GenPLCListener listener = new GenPLCListener(this);
    }

    @Override
    public void pullSlot() {
        // do what you need to do here to implement a pulling of the lever
        int r1 = rand.nextInt(slotList.size());
        int r2 = rand.nextInt(slotList.size());
        int r3 = rand.nextInt(slotList.size());

        reel1lbl.setIcon(slotList.get(r1));
    }
}

public class GenPLCListener implement ActionListener {
    private PullInterface pull;

    public GenPLCListener(PullInterface pull) {
        this.pull = pull;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        pull.pullSlot();
    }
}

相关文章