简体   繁体   English

如何实现wait(); 陈述正确?

[英]How to implement the wait(); statement properly?

I'm getting an issue when I'm trying to make a tic tac toe game.当我尝试制作井字游戏时遇到问题。 The Issue that I'm coming across is presented when I'm trying to use a wait();当我尝试使用 wait(); 时,会出现我遇到的问题; statement in order to pause the game so the player is able to look at who won the game and what the winning squares are, however when I try to run this little chunk of code right here:声明以暂停游戏,以便玩家能够查看谁赢得了游戏以及获胜方格是什么,但是当我尝试在这里运行这段代码时:

            wait(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

It gives me this error code right here:它在这里给了我这个错误代码:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at GameCode.restart(GameCode.java:264)
    at GameCode.xWins(GameCode.java:245)
    at GameCode.check(GameCode.java:171)
    at GameCode.actionPerformed(GameCode.java:70)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$500(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

It describes it to be an IllegalMonitorStateException , however I tried using throw to resolve this problem but it still continues to give me this error.它描述它是一个IllegalMonitorStateException ,但是我尝试使用throw来解决这个问题,但它仍然继续给我这个错误。 Any solutions out there?有什么解决方案吗? For reference here is my code if you need to see any other info:如果您需要查看任何其他信息,请在此处参考我的代码:

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GameCode implements ActionListener {
    
    Random random = new Random();
    JFrame frame = new JFrame();
    JPanel title_panel = new JPanel();
    JPanel button_panel = new JPanel();
    JLabel textfield = new JLabel();
    JButton[] buttons = new JButton[9];
    boolean player1_turn;
    
    
    
    
    GameCode() {
        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,500);
        frame.getContentPane().setBackground(new Color(0,0,0));
        frame.setLayout(new BorderLayout());
        frame.setVisible(true);
        
        textfield.setBackground(new Color(25,25,25));
        textfield.setForeground(new Color(25,255,0));
        textfield.setFont(new Font("TimesRoman", Font.BOLD,75));
        textfield.setHorizontalAlignment(JLabel.CENTER);
        textfield.setText("Tic Tac Toe");
        textfield.setOpaque(true);
        title_panel.setLayout(new BorderLayout());
        title_panel.setBounds(0,0,800,100);
        
        button_panel.setLayout(new GridLayout(3,3));
        button_panel.setBackground(new Color(150,25,25));
        
        for(int j = 0; j < 9; j++ ) {
            
            buttons[j] = new JButton();
            button_panel.add(buttons[j]);
            buttons[j].setFont(new Font("Ink Free", Font.BOLD,120));
            buttons[j].setFocusable(false);
            buttons[j].addActionListener(this);
            
        }
        
        
        title_panel.add(textfield);
        frame.add(title_panel, BorderLayout.NORTH);
        frame.add(button_panel);
        
        Turnone();
        
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        
        for (int i = 0; i < 9; i++) {
            
            if(arg0.getSource()==buttons[i]) {
                if(player1_turn) {
                    if(buttons[i].getText()=="") {
                        buttons[i].setForeground(new Color(255,0,0));
                        buttons[i].setText("X");
                        player1_turn=false;
                        textfield.setText("O turn");
                        check();
                    }
                } else {
                    if(buttons[i].getText()=="") {
                        buttons[i].setForeground(new Color(0,0,255));
                        buttons[i].setText("O");
                        player1_turn=true;
                        textfield.setText("X turn");
                        check();
                    }
                }
            }
        }
    }//Creating the Buttons the player will interact with
    
    public void Turnone() {
        
        for(int i=0; i<9;i++) {
            buttons[i].setEnabled(false);
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        for(int i=0; i<9;i++) {
            buttons[i].setEnabled(true);
        }
        
        if(random.nextInt(2)==0) {
            
            player1_turn = true;
            textfield.setText("X turn");
            
        } else {
            
            player1_turn = false;
            textfield.setText("O Turn");
            
        }
        
    }//Using a random int to decide which player will go first
    
    public void check() {
        //X Wins
        
        if(
                (buttons[0].getText()=="X") &&
                (buttons[1].getText()=="X") &&
                (buttons[2].getText()=="X") 
                ) {
            xWins(0,1,2);
        }
        if(
                (buttons[3].getText()=="X") &&
                (buttons[4].getText()=="X") &&
                (buttons[5].getText()=="X") 
                ) {
            xWins(3,4,5);
        }
        if(
                (buttons[6].getText()=="X") &&
                (buttons[7].getText()=="X") &&
                (buttons[8].getText()=="X") 
                ) {
            xWins(6,7,8);
        }
        if(
                (buttons[0].getText()=="X") &&
                (buttons[3].getText()=="X") &&
                (buttons[6].getText()=="X") 
                ) {
            xWins(0,3,6);
        }
        if(
                (buttons[1].getText()=="X") &&
                (buttons[4].getText()=="X") &&
                (buttons[7].getText()=="X") 
                ) {
            xWins(1,4,7);
        }
        if(
                (buttons[2].getText()=="X") &&
                (buttons[5].getText()=="X") &&
                (buttons[8].getText()=="X") 
                ) {
            xWins(2,5,8);
        }
        if(
                (buttons[0].getText()=="X") &&
                (buttons[4].getText()=="X") &&
                (buttons[8].getText()=="X") 
                ) {
            xWins(0,4,8);
        }
        if(
                (buttons[2].getText()=="X") &&
                (buttons[4].getText()=="X") &&
                (buttons[6].getText()=="X") 
                ) {
            xWins(2,4,6);
        }
        //O Wins
        
        if(
                (buttons[0].getText()=="O") &&
                (buttons[1].getText()=="O") &&
                (buttons[2].getText()=="O") 
                ) {
            oWins(0,1,2);
        }
        if(
                (buttons[3].getText()=="O") &&
                (buttons[4].getText()=="O") &&
                (buttons[5].getText()=="O") 
                ) {
            oWins(3,4,5);
        }
        if(
                (buttons[6].getText()=="O") &&
                (buttons[7].getText()=="O") &&
                (buttons[8].getText()=="O") 
                ) {
            oWins(6,7,8);
        }
        if(
                (buttons[0].getText()=="O") &&
                (buttons[3].getText()=="O") &&
                (buttons[6].getText()=="O") 
                ) {
            oWins(0,3,6);
        }
        if(
                (buttons[1].getText()=="O") &&
                (buttons[4].getText()=="O") &&
                (buttons[7].getText()=="O") 
                ) {
            oWins(1,4,7);
        }
        if(
                (buttons[2].getText()=="O") &&
                (buttons[5].getText()=="O") &&
                (buttons[8].getText()=="O") 
                ) {
            oWins(2,5,8);
        }
        if(
                (buttons[0].getText()=="O") &&
                (buttons[4].getText()=="O") &&
                (buttons[8].getText()=="O") 
                ) {
            oWins(0,4,8);
        }
        if(
                (buttons[2].getText()=="O") &&
                (buttons[4].getText()=="O") &&
                (buttons[6].getText()=="O") 
                ) {
            oWins(2,4,6);
        }
    
    }//Stating all the win conditions for the game
    
    public void xWins(int a, int b, int c) {
        buttons[a].setBackground(Color.GREEN);
        buttons[b].setBackground(Color.GREEN);
        buttons[c].setBackground(Color.GREEN);
        
        for(int i=0; i<9;i++) {
            buttons[i].setEnabled(false);
        }
        
        textfield.setText("X Wins!");
        
        restart();
    }//When Player X wins
    
    public void oWins(int a, int b, int c) {
        buttons[a].setBackground(Color.GREEN);
        buttons[b].setBackground(Color.GREEN);
        buttons[c].setBackground(Color.GREEN);
        
        for(int i=0; i<9;i++) {
            buttons[i].setEnabled(false);
        }
        textfield.setText("O Wins!");
        
        restart();
    }//When Player O wins 
    
    public void restart() { 
        
        try {
            wait(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        
    }
    
    
    
}//GameCode

Here is a simple example using a swing Timer.这是一个使用 swing 定时器的简单示例。

public void restart() { 
    Timer t = new Timer( 1000, evt->{
        //reset and enable the board.
        for(int i=0; i<9;i++) {
            buttons[i].setText("_");
            buttons[i].setEnabled(true);
        }
    }
    t.setRepeats(false);
    t.start();
}

This creates a new timer each time and doesn't keep track of it.这每次都会创建一个新计时器,并且不会跟踪它。 So there are definite improvements to managing the code.因此,管理代码有明确的改进。 It hopefully illustrates a way to schedule events in swing.希望它说明了一种在 swing 中安排事件的方法。

The error you are getting with the wait code is because you have to be synchronized on an object to call wait on it.您收到等待代码的错误是因为您必须在 object 上进行同步才能对其调用等待。 You could replace your wait call to a wait + synchronize to remove the error, but it is not good practice and will make your gui non-responsive while the EDT is waiting.您可以将您的等待调用替换为等待 + 同步以消除错误,但这不是一个好习惯,并且会在 EDT 等待时使您的 gui 无响应。

synchronize(this){
    wait(1000); 
}

You are doing too much on the event thread including checking for wins and waiting.您在事件线程上做的太多了,包括检查胜利和等待。 So the following changes will work in a pinch.因此,以下更改将在紧要关头起作用。

First, put the entire body of the actionPerformed method in a separate thread.首先,将actionPerformed方法的整个主体放在一个单独的线程中。

    @Override
    public void actionPerformed(ActionEvent arg0) {
        new Thread(()-> {
        for (int i = 0; i < 9; i++) {
            
            if(arg0.getSource()==buttons[i]) {
                if(player1_turn) {
                    if(buttons[i].getText().equals("")) {
                        buttons[i].setForeground(new Color(255,0,0));
                        buttons[i].setText("X");
                        player1_turn=false;
                        textfield.setText("O turn");
                        check();
                    }
                } else {
                    if(buttons[i].getText().equals("")) {
                        buttons[i].setForeground(new Color(0,0,255));
                        buttons[i].setText("O");
                        player1_turn=true;
                        textfield.setText("X turn");
                        check();
                    }
                }
            }
        }
        }).start();
    }

Then it will be safe to use sleep in your restart method.然后在重启方法中使用睡眠是安全的。 You could also use a Swing Timer but it is still important to not do too much processing on the event thread.您也可以使用 Swing 计时器,但不要在事件线程上进行太多处理仍然很重要。

public void restart() {
   try {
       Thread.sleep(2000);
   } catch (InterruptedException ie) {
   }
   System.out.println("Waking up");
  
}

But your overall approach has some issues when it comes to painting and handling events.但是在绘制和处理事件时,您的整体方法存在一些问题。 You should check out the Java Tutorials for more on painting and event processing.您应该查看Java 教程以了解有关绘画和事件处理的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM