我正在开发一个简单的 TicTacToe 游戏,该游戏具有“玩家对玩家”模式。
我决定添加一个菜单,玩家可以在其中选择是要与其他玩家还是与计算机一起玩。
但是我不知道如何正确调用菜单项来触发指定的代码。
我尝试了 Action监听器,但是在 ActionListener 中的 ActionListener 似乎不起作用。
我是编程新手,我搜索了各种网站,但似乎找不到解决方案。我只想在用户单击 1-vs-1 和 1-vs-computer 时触发 1-vs-1 的代码当用户从菜单中选择 1-vs-computer 时,将触发>(这部分尚未编写,您可能已经知道了)。
您很少的时间来解决此问题将对我有很大的帮助!
package tictacpractice;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Frame implements ActionListener {
int value=0;
JButton reset;
JButton exit;
JLabel p1;
JLabel p2;
JButton []board;
int turn;
String Checker= "";
String []Checkers= new String[9];
boolean winner=false;
JMenuBar menuBar;
JMenu Menu;
JMenuItem item1,item2;
Frame(){
turn=1;
JFrame frm = new JFrame("TicTacThuss");
frm.setSize(400,400);
menuBar = new JMenuBar();
Menu = new JMenu("Mode");
Menu.setFont(new Font("Ariel", Font.BOLD, 32));
item1 = new JMenuItem("1v1");
item1.setFont(new Font("Ariel", Font.BOLD, 32));
item2 = new JMenuItem("1vc");
item2.setFont(new Font("Ariel", Font.BOLD, 32));
Menu.add(item1);
Menu.add(item2);
menuBar.add(Menu);
frm.setJMenuBar(menuBar);
item2.addActionListener(this);
reset = new JButton("reset");
exit = new JButton ("exit");
p1 = new JLabel("Player X");
p2 = new JLabel("Player O");
board = new JButton[9];
reset.addActionListener(this);
exit.addActionListener(this);
JPanel Lowerpanel= new JPanel();
Lowerpanel.add(reset);
Lowerpanel.add(exit);
JPanel Centralpanel= new JPanel();
Centralpanel.setLayout(new GridLayout(3,3));
//String initiallizer
for(int c=0; c<9; c++){
Checkers[c]="";
}
for(int i=0; i<9; i++)
{
board[i]=new JButton();
Centralpanel.add(board[i]);
board[i].addActionListener(this);
board[i].setFont(new Font("Ariel", Font.BOLD, 72));
}
frm.add(Centralpanel, BorderLayout.CENTER);
frm.add(Lowerpanel, BorderLayout.SOUTH);
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e){
value++;
if(turn==1){
Checker=" X";
}
if(turn==0){
Checker=" O";
}
if(e.getSource()==reset){
for(int i=0; i<9; i++)
{
board[i].setText("");
board[i].setEnabled(true);
winner=false;
Checkers[i]="";
value=0;
turn=1;
}
}
if(e.getSource()==exit){
System.exit(0);
}
for(int i=0; i<9; i++)
{
if(e.getSource()==board[i])
{
if(turn==1)
{
board[i].setText("X");
board[i].setEnabled(false);
Checkers[i]=Checker;
}
else{
if(turn==0)
{
board[i].setText("O");
board[i].setEnabled(false);
Checkers[i]=Checker;
}
}
turn=(turn+1)%2;
}
}
//horizontal
if (Checkers[0].equals(Checkers[1]) &&
Checkers[1].equals(Checkers[2]) &&
!Checkers[0].equals("") ) {
winner = true;
}
else if (Checkers[3].equals(Checkers[4]) &&
Checkers[4].equals(Checkers[5]) &&
!Checkers[3].equals("") ) {
winner = true;
}
else if (Checkers[6].equals(Checkers[7]) &&
Checkers[7].equals(Checkers[8]) &&
!Checkers[6].equals("") ) {
winner = true;
}
//Verticle
if (Checkers[0].equals(Checkers[3]) &&
Checkers[3].equals(Checkers[6]) &&
!Checkers[0].equals("") ) {
winner = true;
}
else if (Checkers[1].equals(Checkers[4]) &&
Checkers[4].equals(Checkers[7]) &&
!Checkers[1].equals("") ) {
winner = true;
}
else if (Checkers[2].equals(Checkers[5]) &&
Checkers[5].equals(Checkers[8]) &&
!Checkers[2].equals("") ) {
winner = true;
}
//Digonals
if (Checkers[0].equals(Checkers[4]) &&
Checkers[4].equals(Checkers[8])
&& !Checkers[0].equals("") ) {
winner = true;
}
else if (Checkers[2].equals(Checkers[4]) &&
Checkers[4].equals(Checkers[6]) &&
!Checkers[2].equals("") ) {
winner = true;
}
//Checker
if(winner){
JOptionPane.showMessageDialog(null, "Player"+Checker+" Wins");
for (JButton i : board) {
i.setEnabled(false);
}
}
else if(!winner && value==9)
{
JOptionPane.showMessageDialog(null," This game is draw ") ;
}
}
}
答案 0 :(得分:1)
在回答您的问题之前,让我对您当前的代码发表一些评论。 目前,通过
item1.addActionListener(this);
item2.addActionListener(this);
reset.addActionListener(this);
exit.addActionListener(this);
您以相同的ActionEvent
方法处理所有actionPerformed
(您的Frame
类中的那个)。
正如您已经注意到的,这使得此actionPerformed
方法非常冗长且难以维护
当添加更多按钮和菜单项时。
因此,我建议您应为按钮提供单独的actionPerformed
方法。
这样做的好处是,每个actionPerformed
方法都非常简短。
而且您不再需要像if (e.getSource() == reset)
这样的代码行。
reset.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// handle click on the "Reset" button
for (int i = 0; i < 9; i++) {
board[i].setText("");
board[i].setEnabled(true);
winner = false;
Checkers[i] = "";
value = 0;
turn = 1;
}
}
});
exit.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// handle click on the "Exit" button
System.exit(0);
}
});
(乍看之下,语法看起来很奇怪,因为它使用了所谓的anonymous classes。)
现在是您的实际问题: 您还应该对菜单项使用相同的模式:
item1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// handle click on the "1-vs-1" menu item
...
}
});
item2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// handle click on the "1-vs-computer" menu item
...
}
});
顺便说一句:从Java 8开始,您可以从上面重写ActionListener
代码
以更简洁,更易读的方式
通过使用所谓的lambda-expressions而不是匿名类:
reset.addActionListener(e -> {
// handle click on the "Reset" button
for (int i = 0; i < 9; i++) {
board[i].setText("");
board[i].setEnabled(true);
winner = false;
Checkers[i] = "";
value = 0;
turn = 1;
}
});
exit.addActionListener(e -> {
// handle click on the "Exit" button
System.exit(0);
});
item1.addActionListener(e -> {
// handle click on the "1-vs-1" menu item
...
});
item2.addActionListener(e -> {
// handle click on the "1-vs-computer" menu item
...
});
最后,您将不再需要actionPerformed
类中的Frame
,
并可以从该课程中删除implements ActionListener
。