需要帮助了解特定的 getter 如何影响我的程序
Need help understanding how a specific getter affects my program
我对编码很陌生(2 个月),我试图在 java 中制作井字棋。我有点不知所措,但我设法使用 swing 创建了它。我的主要问题是在 button1
class。我打算使用 getText()
方法,但最终我认为不需要它。我尝试删除它,但事实证明,没有它,我的 tictactoe 按钮不会切换字母。编译器告诉我它覆盖了 AbstractButton
的 getText()
方法,但我不明白为什么这很重要,因为我认为我从未真正使用过它。我认为这可能是一个范围问题,由它以某种方式被覆盖处理,但我不确定。我试图使用 text
变量来更新带有 setText()
的按钮,但这似乎并没有像我认为的那样工作。我也不明白为什么 3 x 3 gridlayout 似乎大多数时候都能正常工作,但有时添加的按钮数量是错误的。
所以总而言之,该程序(大部分)有效,但我不完全理解 button1
class 是如何工作的。
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));
}
}
}
button1.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 class 定义了一个方法,包括 setText()
(将设置按钮上显示的文本)和 getText()
(将 return显示在按钮上的当前文本)。
您创建了一个 class button1(注意:classes 应该以大写字母开头)。
您向按钮 1 添加了一个动作 class,这意味着当动作被激活时,会发生一些事情。请注意,在 actionPerformed
方法中,您应该调用 setText(text)
来更新显示的值。
您还定义了一个 getText()
方法来覆盖 JButton 中定义的 getText()
方法。如果是有意识的设计决策,这种方法很好。事实上,我认为您应该从 button1 class 中删除 getText()
方法,并允许标准 JButton class 处理更新。现在,您正试图将实例变量 text
与值保持在一起,但该实例变量可能与按钮的实际显示值不一致(考虑另一个 class 调用.setText()
在按钮上)。
编辑:的确,在 ButtonAction 中引用 JButton 的 this
不可用。但是,操作本身包含按下的按钮。
@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 class 可能删除了 String text
实例变量。
您尝试的是尝试通过扩展 AbstractAction
namee button1
来创建自定义 Button
Class 及其 EventHandler
,如我们所见你的问题。
您已经根据自己的定义覆盖了实际上属于 Class AbstractAction
的方法 actionPerformed(ActionEvent Switcher)
(每个按钮的动作事件应该执行什么).
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 buttonArrayList = new 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
。每个 button
都有 actionPerformed()
方法,其中包含 overrided
定义。
现在每个按钮都会根据您给 actionPerformed()
方法的定义执行操作。
谢谢。
我对编码很陌生(2 个月),我试图在 java 中制作井字棋。我有点不知所措,但我设法使用 swing 创建了它。我的主要问题是在 button1
class。我打算使用 getText()
方法,但最终我认为不需要它。我尝试删除它,但事实证明,没有它,我的 tictactoe 按钮不会切换字母。编译器告诉我它覆盖了 AbstractButton
的 getText()
方法,但我不明白为什么这很重要,因为我认为我从未真正使用过它。我认为这可能是一个范围问题,由它以某种方式被覆盖处理,但我不确定。我试图使用 text
变量来更新带有 setText()
的按钮,但这似乎并没有像我认为的那样工作。我也不明白为什么 3 x 3 gridlayout 似乎大多数时候都能正常工作,但有时添加的按钮数量是错误的。
所以总而言之,该程序(大部分)有效,但我不完全理解 button1
class 是如何工作的。
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));
}
}
}
button1.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 class 定义了一个方法,包括 setText()
(将设置按钮上显示的文本)和 getText()
(将 return显示在按钮上的当前文本)。
您创建了一个 class button1(注意:classes 应该以大写字母开头)。
您向按钮 1 添加了一个动作 class,这意味着当动作被激活时,会发生一些事情。请注意,在 actionPerformed
方法中,您应该调用 setText(text)
来更新显示的值。
您还定义了一个 getText()
方法来覆盖 JButton 中定义的 getText()
方法。如果是有意识的设计决策,这种方法很好。事实上,我认为您应该从 button1 class 中删除 getText()
方法,并允许标准 JButton class 处理更新。现在,您正试图将实例变量 text
与值保持在一起,但该实例变量可能与按钮的实际显示值不一致(考虑另一个 class 调用.setText()
在按钮上)。
编辑:的确,在 ButtonAction 中引用 JButton 的 this
不可用。但是,操作本身包含按下的按钮。
@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 class 可能删除了 String text
实例变量。
您尝试的是尝试通过扩展 AbstractAction
namee button1
来创建自定义 Button
Class 及其 EventHandler
,如我们所见你的问题。
您已经根据自己的定义覆盖了实际上属于 Class AbstractAction
的方法 actionPerformed(ActionEvent Switcher)
(每个按钮的动作事件应该执行什么).
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 buttonArrayList = new 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
。每个 button
都有 actionPerformed()
方法,其中包含 overrided
定义。
现在每个按钮都会根据您给 actionPerformed()
方法的定义执行操作。
谢谢。