【问题标题】:Reference clicked JButton inside ActionListener在 ActionListener 中引用单击的 JButton
【发布时间】:2013-08-05 02:08:37
【问题描述】:

我正在尝试使用 swing 编写井字游戏程序,但我似乎遇到了一些问题。在我的匿名内部类中,我尝试为每个按钮设置 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();

}


}

【问题讨论】:

    标签: java swing jbutton actionlistener tic-tac-toe


    【解决方案1】:

    请记住,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
            }
        }
    });
    

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

    【讨论】:

    • 非常感谢。我非常感谢您的帮助,这很有效。
    • 另一个问题。以这种方式确定获胜者的最佳方法是什么?假设我做了一个计数器并且有 ((JButton) source).setText("O");或 ((JButton) source).setText("X");
    • 其实最好的办法就是建立某种模型。这将允许您检查游戏状态并确定选择了哪些单元格以及由谁选择。每次玩家选择一个按钮时,我都会更新模型。此过程的一部分是让模型检查获胜者并触发适当的事件
    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • 我要做的唯一评论是确保您强调一个事实,即在您的第一个示例中,JButton 要么需要是实例变量,要么需要是 final ;)
    【解决方案3】:

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

    最后,我建议在构造函数中设置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();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-25
      • 1970-01-01
      • 2012-07-17
      • 2020-11-01
      • 2012-03-07
      • 2013-11-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多