调用菜单项以触发单独的代码块

时间:2018-12-26 14:05:06

标签: java menu actionlistener tic-tac-toe

我正在开发一个简单的 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 ") ;     
         }

    }

}

1 个答案:

答案 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