Java 在结束方法之前,请等待单击JButton

Java 在结束方法之前,请等待单击JButton,java,swing,jbutton,Java,Swing,Jbutton,我正在编写一个tic tac toe游戏,它在玩家(用户点击按钮)和电脑玩家之间轮流进行 我有一个名为playersTurn()的方法,它需要等到单击JButton后,该方法才会结束,计算机播放器才会轮到它。我读过关于使用线程和wait-notify方法的文章,但我对Java是新手,不知道如何实现它 我想知道是否有一个更简单的方法来克服这个问题,或者这是唯一的方法,如果是的话,有谁能告诉我一个好的教程吗 谢谢你不应该等待和测试什么事情发生, 正确的方法是将Listener设置为Butoon,例如

我正在编写一个tic tac toe游戏,它在玩家(用户点击按钮)和电脑玩家之间轮流进行

我有一个名为
playersTurn()
的方法,它需要等到单击
JButton
后,该方法才会结束,计算机播放器才会轮到它。我读过关于使用线程和
wait-notify
方法的文章,但我对Java是新手,不知道如何实现它

我想知道是否有一个更简单的方法来克服这个问题,或者这是唯一的方法,如果是的话,有谁能告诉我一个好的教程吗


谢谢

你不应该等待和测试什么事情发生, 正确的方法是将Listener设置为Butoon,例如在单击按钮后更改活动播放器。 但是一切都取决于你的代码执行。

正如@HFOE对他说的(+1)你不想在notify and wait中使用
线程
s这真是太复杂了 你的游戏逻辑是不正确的

在开始游戏之前,制定一些框架:

  • 9
    JButton
    s(数组将容纳按钮)
  • JPanel
    使用
    GridLayout(3,3)
    创建tic-tac-toe网格
现在是重要的部分:

  • 玩家开始游戏,然后电脑运行,依此类推
考虑到以上内容,请看我的示例,我所做的基本操作在
ActionListener
中,用于播放器离开后的每个按钮(单击按钮并设置播放器符号),我们称cpu播放的方法为:

导入java.awt.Dimension;
导入java.awt.GridLayout;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.ArrayList;
导入java.util.Random;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
导入javax.swing.UIManager;
导入javax.swing.UIManager.LookAndFeelInfo;
公开课考试{
//为播放器和cpu符号声明变量
专用字符串播放器SYMBOL=“X”;
专用字符串cpuSymbol=“O”;
//用于cpu选择随机块
私有随机r=新随机();
//创建用于保存按钮的arraylist
ArrayList块=新的ArrayList();
//这是一个动作列表,将被添加到每个区块,并允许玩家第一次回合,然后cpu运行
私有ActionListener al=新ActionListener(){
@凌驾
已执行的公共无效行动(行动事件ae){
//球员转身
playerTurn(ae);
//检查玩家离开后是否获胜
checkForWin();
//cpu转数
cpuTurn();
//cpu运行后检查是否有赢家
checkForWin();
}
私有void cpuTurn(){
System.out.println(“CPU停止”);
while(true){
int blockNumber=r.nextInt(9);
System.out.println(blockNumber+“”);
字符串tmp=blocks.get(blockNumber.getText();
if(tmp.等于(“”){
blocks.get(blockNumber).setText(cpuSymbol);
打破
}
}
}
私有void checkForWin(){
System.out.println(“检查是否获胜…”);
}
私人void playerTurn(ActionEvent ae){
System.out.println(“玩家离开”);
JButton block=(JButton)ae.getSource();
block.setText(playerSymbol);
}
};
公开考试(){
初始化组件();
}
私有组件(){
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel board=newjpanel(newgridlayout(3,3));//创建gridlayput以保持按钮
//创建块/按钮以保持X和Y
创建块(块);
//向电路板添加按钮/块
填充板(块、板);
//将线路板添加到JFrame内容窗格
框架。添加(板);
frame.pack();
frame.setVisible(true);
}
专用空心填充板(ArrayList块、JPanel板){
用于(JButton块:块){
添加(块);
}
}
专用void createBlocks(ArrayList块){
对于(int i=0;i<9;i++){
//创建大小为50,50的新按钮
JButton块=新JButton(){
@凌驾
公共维度getPreferredSize(){
返回新维度(50,50);
}
};
block.addActionListener(al);//将actionlistner添加到按钮
块。添加(块);
}
}
公共静态void main(字符串[]args){
//在EDT上设置L&F并创建UI
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
尝试{//设置L&F
for(LookAndFeelInfo:UIManager.getInstalledLookAndFeels()){
if(“Nimbus”.equals(info.getName())){
UIManager.setLookAndFeel(info.getClassName());
打破
}
}
}捕获(例外e){
//如果Nimbus不可用,您可以将GUI设置为其他外观。
}
//创建用户界面
新测试();
}
});
}
}

若要获得更好的帮助,请尽快发布一篇文章,我认为您应该阅读有关observer设计模式的内容。不,您根本不想在此处使用“等待-通知”。您希望为游戏指定一个布尔player0Turn或player1Turn变量(您的选择),该变量根据轮到谁来更改,然后您可以根据该变量的状态来确定程序的行为。
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

public class Test {
    //declare variables for player and cpu symbol

    private String playerSymbol = "X";
    private String cpuSymbol = "O";
    //used for cpu to select random block
    private Random r = new Random();
    //create arraylist to hold buttons
    ArrayList<JButton> blocks = new ArrayList<>();
    //this is the action listner that will be added to each block and will allow player the first turn then cpu goes
    private ActionListener al = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {

            //players turn
            playerTurn(ae);

            //check for win after player gone
            checkForWin();

            //cpu turn
            cpuTurn();

            //check for a win after cpu goes
            checkForWin();
        }

        private void cpuTurn() {
            System.out.println("CPU goes");
            while (true) {
                int blockNumber = r.nextInt(9);

                System.out.println(blockNumber + "");
                String tmp = blocks.get(blockNumber).getText();

                if (tmp.equals("")) {
                    blocks.get(blockNumber).setText(cpuSymbol);
                    break;
                }
            }
        }

        private void checkForWin() {
            System.out.println("Checking for a win...");
        }

        private void playerTurn(ActionEvent ae) {
            System.out.println("Player goes");
            JButton block = (JButton) ae.getSource();
            block.setText(playerSymbol);
        }
    };

    public Test() {
        initComponents();
    }

    private void initComponents() {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel board = new JPanel(new GridLayout(3, 3));//create gridlayput to hold buttons

        //create blocks/Jbuttons to hold X and Y
        createBlocks(blocks);
        //add buttons/blocks to the board
        fillBoard(blocks, board);
        //add board to JFrame content pane
        frame.add(board);

        frame.pack();
        frame.setVisible(true);
    }

    private void fillBoard(ArrayList<JButton> blocks, JPanel board) {
        for (JButton block : blocks) {
            board.add(block);
        }
    }

    private void createBlocks(ArrayList<JButton> blocks) {
        for (int i = 0; i < 9; i++) {

            //create new button with a size of 50,50
            JButton block = new JButton() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(50, 50);
                }
            };
            block.addActionListener(al);//add the actionlistner to the button
            blocks.add(block);
        }
    }

    public static void main(String[] args) {
        //set L&F and create UI on EDT
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {

                try {//set L&F
                    for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                        if ("Nimbus".equals(info.getName())) {
                            UIManager.setLookAndFeel(info.getClassName());
                            break;
                        }
                    }
                } catch (Exception e) {
                    // If Nimbus is not available, you can set the GUI to another look and feel.
                }

                //create UI
                new Test();
            }
        });
    }
}