I have an application in which it would be very convenient for me to have a mouse click event emulate a user typing in a certain string to standard input. So I was wondering, is there a way in code to WRITE to standard in? I realize it’s a bit of a hack, but it would work very well for what I need to do.
EDIT (in response to Hovercraft’s EDIT2):
Thanks. I understand how that code keeps the human player from moving a piece when they shouldn’t. What I don’t understand is how you are envisioning the main game loop. Would you mind writing code to show me what you’re thinking for that? Are you just picturing a busy-wait loop that constantly generates new computer moves and calls your Move() method (most of the time being rejected while it’s waiting for the human player to make a move)? Something like this?
public void gameLoop()
{
while (gameNotOver)
{
Move compMove = generateComputersNextMove();
move(blackPlayer, compMove); // where the blackPlayer is the computerPlayer
}
}
You state:
You don’t want to block your program (not in an event-driven program) so much as change the state of your GUI, and base your response to user’s input on this state. Your attempted solution is a linear way of thinking, and doesn’t work well with Swing or other event driven GUI’s.
For instance as a simple example consider giving your program a boolean variable,
And change this to true in the JLabel’s MouseListener after the JLabel has been clicked. Then only respond to other user input if the boolean is true.
Or another possible solution: if you want to activate a JButton after a JLabel has been pressed, then make the JButton disabled, and call setEnabled(true) on the JButton from within the JLabel’s MouseListener.
The key is to think Event-Driven Programming.
The other key when asking questions like this in this forum is not to ask us a code-specific question, but rather a behavior-specific question. The true question here is not how to write to the standard in, but rather how to get your program to pause and await user input — that’s a big difference.
Finally, if you need more specific and better recommendations, please fill us in on the details of your problem, and certainly ask questions if any of this is confusing. Best of luck!
Edit 1
You’re likely going to have several classes including GUI and non-GUI classes managing this application, and the non-GUI classes can include:
The Game class will have fields including a Player field called
turnthat will hold a reference to whoever’s turn it is. So say your Game class holds two Player variables, humanPlayer and computerPlayer. The turn variable will hold one or the other of these objects, and how Player responds will depend on what object is held by turn.The Game class will have a loop of sorts, a game loop, that alternates between telling the humanPlayer object and the computerPlayer object that its their turn to move.
So say its the computer’s turn, and it is taking a while to calculate the next best move. If meanwhile the human player tries to drag a chess piece on the GUI, the GUI will inform the Game class of the human’s attempt to move, the Game class will check if it’s the human’s turn (by checking
if (turn == humanPlayer)) and if it’s not the human’s turn, Game will inform the GUI this, and the GUI will set the piece back to where it was and perhaps pop up a warning message.After the computer has requested Game to move its piece, Game will tell the GUI to move the computer’s piece, and then Game will set turn = humanPlayer, now allowing the human player to move. After humanPlayer tries to move, the GUI will tell Game of the human’s attempted move. Game will check if its a valid move, and if so, will tell computerPlayer that it should now make a move.
Note that when I say “tell”, I mean that it will call a public method on that object.
Edit 2
I mean something sort of like this:
So if the human player tries to move the GUI will move(…) for the human player, but the Game object won’t respond unless it is in fact the human’s turn.
Edit 3
makeMove()method added to PlayerNote that the Game’s
move(...)method may be all the game loop that is needed, especially if the ComputerPlayer’smakeMove(...)method tells the AI engine to create the next best move and then calls Game’s move(…) method again:Both players would call
game.move(...)when they have figured out the move, which makes the Game prompt the next player to move…. until game is over.Note, that this is not a running program and not meant to be, but more of a mock-up to illustrate possible game logic. I’ve not done something like this, and there are probably better and cleaner ways to do this, but I just want to get the point across of ways of implementing turn-based logic in an event-driven GUI program.
Edit 4
Compile and run the following simple event driven GUI:
You’ll see that there’s a JButton held in a JPanel. You as the user can press the button any time you’d like, but it will only respond when the light is green (when the go boolean variable is true). This is one example where the button’s behavior, whether it responds to presses or not, depends on the state of the class, whether go is true or not. Once the GUI is set up — the constructor has been called, it has been placed in a JFrame, and is displayed, there’s no code that blocks or anything like that. There’s a Swing Timer whose only job is to toggle go’s value and repaint the JFrame, but that’s it.