Member Avatar for getack

Hello All!

I am making a simple four-in-a-row style game where 2 players can play against eachother. This is part of an AI course I'm taking where we should demonstrate the machine (the AI) playing against the player.

The game part of the game and the gui are completely separated. I want to keep things this way prefarably. The game can be player vs player, player vs AI, AI vs AI (to test different AI models) and so on.

When the game is started, I create a jFrame window asking for some player info (name, AI type, player vs player or player vs AI etc). When the user clicks on 'Play' the jFrame creates a "GameType" object containing all the relevant info nescesary to initialize the rest of the game.

How do I make the jFrame wait for the 'play' button and then send the info to the rest of the game?

See the code for a better idea


The Main class:

public class Main {
    public static void main(String[] args) {        
        Game game = new Game();        
        game.run();        
    }
}

The Game class:

public class Game {
    
    GameType GT;

    public void run(){
        
        if (init()){
            gameLoop();
        }        

    }

    private void gameLoop(){        
        while (true){
            //the main game loop
        }                
    }

    private boolean init(){
        
        PlayerInfo playerInfo = new PlayerInfo();        
        playerInfo.display();

        GT = playerInfo.getGameType();        
        System.out.println(GT.getPlayer1());        
        
        //and eventually if everything's fine,
        return true;
        
    }

}

And finally the GUI PlayerInfo class:

public class PlayerInfo extends javax.swing.JFrame {

    private GameType GT;    
    private boolean OKPressed = false;

    public PlayerInfo() {
        initComponents();
    }

    /*the event listener function for the 'play' button*/
    private void btnPlayActionPerformed(java.awt.event.ActionEvent evt) {

        GT = new GameType(/*all relevant info will be inserted here*/);

        OKPressed = true;        
        System.out.println("OK Pressed");        
        
        //this.dispose();
    }


    public void display() {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new PlayerInfo().setVisible(true);
            }
        });
    }    

    
    void waitForOKButton(){
        
        System.out.println("waiting...");
        while (OKPressed == false){}
        System.out.println("done waiting");
    }
    
    public GameType getGameType(){
        waitForOKButton();
        
        System.out.println("senting GT!");
        
        return GT;
    }
}

I am using netbeans and a lot of the code for the PlayerInfo class was left out. The actionPerformed() method is the one that's called when the button is pressed.

As you can see I tried spinning on a boolean variable that turns true when the button is pressed. For some reason it keeps on spinning and the waitForOK() never returns?

What am I doing wrong? Or is my train of thought completely wrong?

The program should be event driven not spinning in a loop. The code waits for the user to do something (an event) and then reacts to that event. It is not executing in a loop while it is waiting. It has returned to the JVM and waits for the JVM to call a listener when the next event happens.

having your application perform a task by clicking a button can easily be done by using ActionListener. there are other Listeners that can help you out as well, so no, I'm not saying this solution is 'the one and only'

Member Avatar for getack

Okay, how should I do it then?

I basically want to send the game info back to the Game object after the user has clicked on 'play'.

Let me just explain the flow, maybe there is a better alternative than the events thing:

Main program is started -> Game object is created -> Game object creates PlayerInfo -> PlayerInfo gets game type info and creates a GameType object -> PlayerInfo sends this GameType back to the Game object -> Game sets up the game according to the info.

The whole events business is a wee bit new for me still, so bear with me, please :)

well, you add a button to your screen, you add an ActionListener to that button, you implement the actionPerformed method and add your logic in there. I'm sure there are tons of examples on the net an easy google query would bring up.

Member Avatar for getack

That is what I did. On line 11 of my PlayerInfo class I have the listener for the button. When the button is pressed, this listener will populate the GameType object with the relevant info coming from other components on the window.

I then have a function getGameType() on line 38 that returns this newly created GameType object. But this function must wait until afterthe GameType is created before it actually returns it.

The Game object creates the PlayerInfo object, and then immediately asks for the GameType (Game class - line 21 to 25), which should only return after GameType has been created.

Should my eventlistener fire an event that the GameType is ready to be sent?

no, just check:

if ( gameType != null ){
runYourCode();
}
else{
error("Game type isn't created yet");
}

Make PlayerInfo playerInfo a field, not a local variable.
Remove Game.GT and PlayerInfo.getGameType().
Whenever you used Game.GT, use Game.playerInfo.GT. Wrap it with a getter for usability.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.