需要帮助了解特定的getter如何影响我的程序



我对编码非常陌生(2个月),我试图用java制作Tic-Tac-Toe。我有点不知所措,但我设法用挥杆创造了它。我的主要问题是在button1课上。我本来打算使用getText()方法,但最终不需要它,我想是这样。我试着删除它,但事实证明,如果没有它,我的tictactoe按钮就无法切换字母。编译器告诉我,它会覆盖AbstractButtongetText()方法,但我不明白为什么这有什么关系,因为我从未真正使用过它。我想这可能是一个范围问题,它被覆盖了,但我不确定。我试图使用text变量用setText()更新按钮,但这似乎没有像我认为的那样起作用。我也不明白为什么3乘3的网格布局在大多数时候似乎都能正常工作,但有时添加的按钮数量是错误的。

所以总的来说,这个程序(大部分)是有效的,但我并不完全理解button1类是如何工作的。

TicTacToe.java

import java.awt.*;
import java.util.*;
import javax.swing.*;
public class TicTacToe extends JFrame {
public static void main(String[] args) {
    JFrame window = new JFrame("Tic-Tac-Toe");
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setVisible(true);
    window.setSize(600, 600);
    window.setLayout(new GridLayout(3, 3));
    ArrayList<button1> buttonArrayList = new ArrayList<>(9);
    for (int i = 0; i < 9; i++) {
        button1 newbutton = new button1();
        buttonArrayList.add(newbutton);
        window.add(buttonArrayList.get(i));
    }
}
}

按钮1.java

import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
public class button1 extends JButton {
int value = 0;
String text = "";
public button1() {
    class ButtonAction extends AbstractAction {
        public ButtonAction() {}
        @Override
        public void actionPerformed(ActionEvent Switcher) {
            System.out.println(text + " " + value);
            value++;//value is a relic from earlier attempts that i just felt like keeping.
            if (text.equals("O")) {
                text = "X";
            } else if (text.equals("X")) {
                text = "";
            } else if (text.equals("")) {
                text = "O";
            }
        }
    }
    this.setAction(new ButtonAction());
    this.setText(text);
    this.setFont(new Font("Arial",Font.PLAIN,120));
}
public String getText()// <----culprit
{
    return text;
}
}

JButton类定义了一个方法,包括setText()(将设置按钮上显示的文本)和getText()(将返回显示在按钮上的当前文本)。

您创建了一个类按钮1(注意:类应该以大写字母开头)。

您向button1类添加了一个Action,这意味着当该操作被激活时,会发生一些事情。请注意,在actionPerformed方法中,应该调用setText(text)来更新显示的值。

您还定义了一个getText()方法,它覆盖了JButton中定义的getText()方法。如果这是一个有意识的设计决策,那么这种方法是可以的。实际上,我认为应该从button1类中删除getText()方法,并允许标准JButton类处理更新。现在,您正试图将实例变量text与值保持一致,但该实例变量可能与按钮的实际显示值不一致(考虑按钮上调用.setText()的另一个类)。

EDIT:确实,引用ButtonAction中JButton的this不可用。但是,Action本身包含被按下的按钮。

    @Override
    public void actionPerformed(ActionEvent e)
    {
        JButton btn = (JButton)e.getSource();
        // if desired, String cur = btn.getText() may be called to find the
        //  current setting; get and process if needed
        btn.setText(WHAT_EVER_TEXT);
    }

然而,除非处理当前文本是一个特定的要求(允许选择O到X到空白),否则我会实现一些跟踪当前转弯的功能。这段代码是我正在试验的东西,它有好的和坏的地方(正如它所说明的):

static class TurnController
{
    // whose turn it is; start with X
    private Player whoseTurn = Player.X;
    // the instance variable
    private static final TurnController instance = new TurnController();

    private TurnController()
    {
    }
    public static Player currentTurn()
    {
        return instance.whoseTurn;
    }
    public static Player nextTurn()
    {
        switch (instance.whoseTurn) {
        case X:
            instance.whoseTurn = Player.O;
            break;
        case O:
            instance.whoseTurn = Player.X;
            break;
        }
        return instance.whoseTurn;
    }
    public static String getMarkerAndAdvance()
    {
        String marker = currentTurn().toString();
        nextTurn();
        return marker;
    }
    enum Player
    {
        X,
        O,
        ;
    }
}

使用此TurnController,actionPerformed变为:

    @Override
    public void actionPerformed(ActionEvent e)
    {
        JButton btn = (JButton)e.getSource();
        btn.setText(TurnController.getMarkerAndAdvance());
    }

并且Button1类可以移除CCD_ 19实例变量。

您尝试的是通过扩展AbstractAction名称button1来创建自定义Button类及其EventHandler,正如我们在您的问题中看到的那样。

您已经根据自己的定义覆盖了方法actionPerformed(ActionEvent Switcher),它实际上属于类AbstractAction(每个按钮的动作事件应该执行什么)。

 class ButtonAction extends AbstractAction {
        public ButtonAction() {}
        @Override
        public void actionPerformed(ActionEvent Switcher) { // Your Definition For actionPerformed..
            System.out.println(text + " " + value);
            value++;//value is a relic from earlier attempts that i just felt like keeping.
            if (text.equals("O")) {
                text = "X";
            } else if (text.equals("X")) {
                text = "";
            } else if (text.equals("")) {
                text = "O";
            }
        }
    }
    this.setAction(new ButtonAction()); // add ActionListener to each Button.
    this.setText(text); // Setting Text to each Button
    this.setFont(new Font("Arial",Font.PLAIN,120)); //add Font to each Button.
}

现在在这个代码中。

ArrayList按钮ArrayList=新的ArrayList<>();

for (int i = 0; i < 9; i++) {
    button1 newbutton = new button1(); // Creating 9  new buttons.
    buttonArrayList.add(newbutton); // add each button into the ArrayList.
    window.add(buttonArrayList.get(i)); // each Button to the the AWT Window.
}

以上代码将生成9按钮并将其添加到您的AWT Window中。每个CCD_ 28具有包含CCD_ 30定义的CCD_。

现在,每个按钮将根据您给actionPerformed()方法的定义执行操作。

谢谢。

最新更新