Java 引用在 ActionListener 中单击 JButton

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18049680/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:04:25  来源:igfitidea点击:

Reference clicked JButton inside ActionListener

javaswingjbuttonactionlistenertic-tac-toe

提问by Amloelxer

I'm trying to write a Tic Tac Toe program using swing, but I seem to having some trouble. In my anonymous inner classes I attempt to set up the actionListener for each of my buttons, but I'm having trouble finding the type or the variable which will allow me to reference the buttons and set them to either X or Y. I tried e.getSource().setText() in my anonymous classes, but that came back with errors. Any thoughts? Thanks! Alex

我正在尝试使用 Swing 编写 Tic Tac Toe 程序,但我似乎遇到了一些麻烦。在我的匿名内部类中,我尝试为我的每个按钮设置 actionListener,但我无法找到类型或允许我引用按钮并将它们设置为 X 或 Y 的变量。我试过 e .getSource().setText() 在我的匿名类中,但返回错误。有什么想法吗?谢谢!亚历克斯

import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TicTacToe  {

public JFrame frame;
public JLabel label;
public JPanel panel;

public static int counter;



public void go()
{ 
    frame = new JFrame("TicTacToe");
    frame.setSize(500, 500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    panel = new JPanel();
    panel.setLayout(new GridLayout(3,3,10,10));
    frame.add(BorderLayout.CENTER, panel);
    label= new JLabel("TIC TAC TOE");
    frame.add(BorderLayout.NORTH, label);

    ; 


    JButton button1 = new JButton("Button 1");
    JButton button2 = new JButton("Button 1");
    JButton button3 = new JButton("Button 1");
    JButton button4 = new JButton("Button 1");
    JButton button5 = new JButton("Button 1");
    JButton button6 = new JButton("Button 1");
    JButton button7 = new JButton("Button 1");
    JButton button8 = new JButton("Button 1");
    JButton button9 = new JButton("Button 1");





    button1.addActionListener(new ActionListener(){ 
        public void actionPerformed(ActionEvent e)
        {


        }
    });

    button2.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {

        }
    });

    button3.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {

        }
    });

    button4.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {

        }
    });

    button5.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {

        }
    });

    button6.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {

        }
    });

    button7.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {

        }
    });

    button8.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {

        }
    });

    button9.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {

        }
    });

    panel.add(button1);
    panel.add(button2);
    panel.add(button3);
    panel.add(button4);
    panel.add(button5);
    panel.add(button6);
    panel.add(button7);
    panel.add(button8);
    panel.add(button9);
    frame.setVisible(true);
    panel.setVisible(true);

}


public static void main(String[] args)
{
    TicTacToe gui = new TicTacToe();
    gui.go();

}


}

采纳答案by MadProgrammer

Remember, ActionListenercan be used on a number of different types of components, so the source reference is generalized. You need to cast to back to the expected value

请记住,ActionListener可以在许多不同类型的组件上使用,因此源参考是通用的。您需要强制转换回预期值

button9.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e)
    {
        Object source = e.getSource();
        if (source instanceof JButton) {
            JButton btn = (JButton)source;
            // Go ahead and do what you like
        }
    }
});

While I know your ActionListeneras it stands can pretty much guarantee that the source type of the Objectwill be a JButton, I never like blindly casting objects, but that's me

虽然我知道你的ActionListener现状几乎可以保证 的源类型Object是 a JButton,但我从不喜欢盲目地投射对象,但这就是我

回答by Kevin Sheehan

If you are receiving errors then you should post them but I am assuming it is because you aren't asserting that the source object is in fact a button. There are two straightforward solutions to what you are doing.

如果您收到错误,那么您应该发布它们,但我假设这是因为您没有断言源对象实际上是一个按钮。您正在做的事情有两种直接的解决方案。

Firstis that since you are only adding one action listener to each button, you can assume that it is the object that the action event is referring to. Just note that the button either needs to be an instance variable or declared final:

首先,由于您只向每个按钮添加一个动作侦听器,因此您可以假设它是动作事件所引用的对象。请注意,按钮要么需要是一个实例变量,要么声明为 final:

    button1.addActionListener(new ActionListener(){ 
        @Override
        public void actionPerformed(ActionEvent e)
        {
            button1.setText("X/Y");
        }
    });

Second,which would fix the cause of your error, is by asserting that the ActionEvent source object is in fact a button. This is done by checking that the source is an instance of JButton:

其次,可以通过断言 ActionEvent 源对象实际上是一个按钮来修复错误原因。这是通过检查源是否是 JButton 的实例来完成的:

    button1.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() instanceof JButton) {
                ((JButton) e.getSource()).setText("X/Y");
            }
        }
    });

回答by Pandacoder

I went through and cleaned up your code a little bit. I'm not quite sure why your code had errors, but I didn't get any. I suggest, since you have common code, to reuse it like I did in an array. I also added a booleanto switch between players on each button click.

我仔细检查并清理了您的代码。我不太确定为什么你的代码有错误,但我没有得到任何错误。我建议,因为你有公共代码,像我在数组中那样重用它。我还添加了一个boolean在每次点击按钮时在玩家之间切换。

Lastly, I suggest setting up the JFrame in the constructor, or in a private method called by the constructor (more complex user interfaces might have a lot of code, and breaking it up is a good habit for maintainability of your code) like I showed below.

最后,我建议在构造函数中或在构造函数调用的私有方法中设置 JFrame(更复杂的用户界面可能有很多代码,分解它是代码可维护性的好习惯),就像我展示的那样以下。

import javax.swing.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TicTacToe {
    public static final boolean PLAYER_X = false;
    public static final boolean PLAYER_O = true;

    public static int counter;

    private JFrame frame;
    private JLabel label;
    private JPanel panel;
    private JButton[] buttons;
    private boolean player;

    public TicTacToe() {
        frame = new JFrame("TicTacToe");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        panel = new JPanel();
        panel.setPreferredSize(new Dimension(500, 500));
        panel.setLayout(new GridLayout(3, 3, 10, 10));
        frame.add(BorderLayout.CENTER, panel);

        label = new JLabel("TIC TAC TOE");
        frame.add(BorderLayout.NORTH, label);

        /* Set the initial player turn to player X */
        player = PLAYER_X;

        /* Create the JButtons  */
        buttons = new JButton[9];

        /* Loop through and set all of them up */
        for (int i = 0; i < buttons.length; i++) {
            buttons[i] = new JButton();
            buttons[i].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (e.getSource() instanceof JButton) {
                        ((JButton)e.getSource()).setText(player ? "O" : "X"); /* Set button text */
                        player = !player; /* Switch turns */
                    }
                }
            });

            /* Add all of the buttons to the panel. */
            panel.add(buttons[i]);
        }

        /* Pack the frame to the contents. Basically a "fit to contents". */
        frame.pack();
    }

    public void go() {
        frame.setVisible(true);
        panel.setVisible(true);
    }

    public static void main(String[] args) {
        TicTacToe gui = new TicTacToe();
        gui.go();
    }
}