im creating a game using java language. I am new to GUI. I want to be able to somehow loop a frame. For example, if the user pressed 2 players, the second frame should be able to show twice like "Player 1 name: " then after pressing enter "player 2 name: " should be the next one and then after pressing next another frame will show. I want to be able to update my GUI every time the enter button is clicked, and limit the update depending on how many players was chosen. The images shown below have different .java files
while(i < game.getnPlayers()) {
if (action.getActionCommand().equals("enter")) {
// codes
}
i++;
}
im trying to start with this code, but when i do. it doesnt get updated
I see you have tagged the post with IntelliJ-idea, so I am assuming you are using the GUI designer. Graphical user interfaces use listeners to listen for certain input (OnMouseClick, ActionListener and so on), and then performs methods you assign to the listener. I would suggest reading some documents or watching some videos on the topic before moving on with your game.
A source from oracle on writing Event listeners
A video on making Java Swing GUIs using IntelliJ
Hope this helps! Good luck!
On your GUI class you must have the button function. There you can create an function for when the button is pressed (in this case the "ENTER"), then you will see how many players were selected.
Related
I've read through a dozen or so actionlistener/loop related questions here, but I'm not sure I've found my answer. I started on my first large Java project, a text RPG that's spiraled into around 5K lines of logic and game features which was functioning as intended using just the console - when I decided I'd try to build a Java swing GUI for it instead. Here's my problem:
I use a Room object which handles the description of where the player is at and also has an array of options for the player to choose next which it creates dynamically based on what cell the room's id is in on a csv file and what is beside it. I stopped outputting this to the console and instead started creating JButtons based on the options array like so:
public void showNarrate(){
add(dd,gridConstraints);
optionCopy.clear();
int i = 0;
for(JButton j : optionButtons){
//adding and formatting buttons to gridBagConstraint I also set actionCommand for each button to the triggerValue (ID of the next room which the button should take the player to)
}
//I tried using a copy of my JButton array here so I could have something to iterate over in actionListener after clearing out the original
//(Since it needs to be cleared so the next Room's buttons can be built after the player chooses an option)
for(JButton j : optionButtons){
optionCopy.add(j);
}
optionButtons.clear();
//dd is a seperate drawingComponent I used for outputting room descriptions which may be totally unnecessary at this point :/
dd.repaint();
setVisible(true);
}
Over in actionlistener (Same class) this is how I tried to swing it:
for(JButton j : optionCopy){
if(e.getActionCommand().equals(j.getActionCommand())){
Main.saveRoom = Main.currentRoom;
Main.currentRoom = j.getActionCommand();
System.out.println(Main.currentRoom);
}
}}
Then in my main class I call:
narrator.narrate(currentRoom, saveRoom); which takes care of some other logic concerning locked doors, encounters, etc.
Also in Main loop are some other methods related to autosave and tracking which rooms the player has visited. I know from other q/a i'v read on here that this is all pretty bad design, and I'm sttarting to understand that now, but my issue is this:
The first room of the game loads up fine, when I click a button it outputs to console(Just for testing) the correct trigger value of the room the button should be calling, so I'm getting that far, but how can I call the same method over again now?
-If I call narrate from actionListener it will wind up calling itself again and complain about ConcurrentModification.
-If I try to keep a loop going in my Main class it will keep looping and won't allow for the player to actually choose a button.
I've never used threads before, which I wonder might be the answer,and the closest thing to a related answer I've found is this:
Java: Method wait for ActionListener in another class
but I don't think moving actionListener to Main class would resolve my problem which is actionListener winding up calling itself recursively. And as for the observer-observable pattern... I just can't understand it :(
I appreciate any and all help, I've learned a LOT trying to make this thing work without seeking help as much as possible but this has stumped me.
Your loop in actionPerformed only checks whether a JButton exists in your optionList with the given actionCommand. However this can be done before actually doing something:
boolean contained = false;
for (JButton j : optionButtons)
if (j.getActionCommand().equals(e.getActionCommand()))
contained = true;
if (contained) {
// change room
}
now you can call narrate because you have finished iterating over the collection beforehand and will not get a ConcurrentModificationException
I wrote a simple little maze game for a terminal which repeatedly asks the user to do something (e.g. "In which direction would you like to go? [N/E/S/W]"). I have a navigate() method running in a loop that fires off these questions, stores their answers and does something depending on the answer.
public enum Dir (N, E, S, W);
public void navigate() {
Dir nextDir = utils.askDirection("Which way do you want to go?");
// Do stuff with answer, like changing position of user in maze
}
Now, I've written a simple GUI for my game. I deliberately put all the references to the terminal in a ConsoleUtils class which implements a Utils interface (this has methods like askQuestion()) - the idea being that I could create a GuiUtils class and have my game either as a terminal game or as a GUI game.
The problem is that the navigate method asks the user a question and then "waits" for the response, which the Utils class gives it by using a Scanner to read the newest line of input. However if I use Event Listeners for the new N/E/S/W buttons in my GUI, they fire off events regardless whether the navigate method has asked for one or not.
--> Image of GUI
Is there any way I can combine this or do I need to write a new navigate method for the GUI?
(To be honest, I'm also not entirely sure whether my GUI class should instantiate a game class, in which case the logic for navigate could end up in a GUI method anyway, or whether the game should have a GUI. I haven't written any code for the event listener either yet, since I'm not sure which class should be calling which. This is probably a separate question.)
Your text based game has a loop that repeatedly asks questions to gather user input. Swing provides this loop for you by continually executing Runnable blocks of code that have been posted to the EventQueue. For example, when the user presses a button labeled E, code is posted to the queue that invokes your ActionEvent implementation to handle your game's interpretation of the move east command.
For reference, a complete example of a very simple guessing game is examined here. In pseudocode, the corresponding text based game might look like this:
initialize
loop
prompt "Guess what color!"
get chosenColor
if chosenColor = actualColor
say "You win!"
reset game
else
say "Keep trying."
end loop
A more elaborate game cited there includes the original text-based source.
I'm currently programming a game in java and am using an interface to handle input/output for the game. I currently have a text interface working properly. I'm using code similar to the following:
while (moveExists())
{
String in = interface.getInput();
processInput(in);
interface.displayOutput(this.getState);
}
The text only interface works because it pauses to wait for input, but I am not sure how to accomplish a similar behaviour in a GUI implementation. How may I 'wait' for input from an actionListener?
If not, I'll probably use code less like a game loop and more like a finite state machine so that I don't need to deal with two different threads trying to co-ordinate their actions.
You could simply start a GUI (that it has its own separated thread) containing a text area and maybe a button or something like that, then you add an ActionListener to the text area or button and then you execute the code you need when the Listener is triggered (i.e. some code has been inserted or button clicked).
Another story if you have also another 'background' thread that needs to run in a loop...
I have developed virtual keyboard module, it contains 2 classes
KBM (the module itself) (on enter press it sets value of String data to the text i typed in KBMListener, and Boolean changed to true in KBMListener)
KBMListener
MainFrame
What is doing mainFrame:
When I run the program MainFrame loads the GUI and starts "while(true)" loop in "public void run()". This loop look like :
while(true){
if(status_changed){
jTextArea.setText(getKbml().getData());
getKbml.setStatus_changed(false);
}
sleep(500);
}
The boolean status_changed is changed in a keyboard Listener.
KBM is the virtual keyboard. When the user type text and press enter, it set the String data to text typed and boolean status_changed to true in KBMListener.
KBML just connects the MainFrame with KBM and loads the keyboard from KBM everytime the user clicks into textarea in mainframe.
What I want is every 0.5 sec or instantly get value to mainframe when enter is pressed.
While loop is working good, but cpu usage is around 12% on 1.6GHz dualcore processor.
I heard about callback but I can not understand how it works. I hope somebody can help me... Try to avoid document listener please.
What you'll want to look into is the Observer design pattern. It uses an interface to notify 'listeners' of changes, and is often the answer to infinite loops. You can find a simple implementation example + more information here : http://java.dzone.com/articles/design-patterns-uncovered
Or simply search the web for "observer pattern java".
This question already has an answer here:
How to stop Java from running the entire code with out waiting for Gui input from The user
(1 answer)
Closed 5 years ago.
I'm a rather basic programmer who has been assigned to make a GUI program without any prior experience with creating a GUI. Using NetBeans, I managed to design what I feel the GUI should look like, and what some of the buttons should do when pressed, but the main program doesn't wait for the user's input before continuing. My question is, how do I make this program wait for input?
public class UnoMain {
public static void main(String args[]) {
UnoGUI form = new UnoGUI(); // GUI class instance
// NetBeans allowed me to design some dialog boxes alongside the main JFrame, so
form.gameSetupDialog.setVisible(true); // This is how I'm trying to use a dialog box
/* Right around here is the first part of the problem.
* I don't know how to make the program wait for the dialog to complete.
* It should wait for a submission by a button named playerCountButton.
* After the dialog is complete it's supposed to hide too but it doesn't do that either. */
Uno Game = new Uno(form.Players); // Game instance is started
form.setVisible(true); // Main GUI made visible
boolean beingPlayed = true; // Variable dictating if player still wishes to play.
form.playerCountLabel.setText("Players: " + Game.Players.size()); // A GUI label reflects the number of players input by the user in the dialog box.
while (beingPlayed) {
if (!Game.getCompleted()) // While the game runs, two general functions are repeatedly called.
{
Player activePlayer = Game.Players.get(Game.getWhoseTurn());
// There are CPU players, which do their thing automatically...
Game.Turn(activePlayer);
// And human players which require input before continuing.
/* Second part of the problem:
* if activePlayer's strategy == manual/human
* wait for GUI input from either a button named
* playButton or a button named passButton */
Game.advanceTurn();
// GUI updating code //
}
}
}
}
I've spent about three days trying to figure out how to integrate my code and GUI, so I would be grateful if someone could show me how to make this one thing work. If you need any other information to help me, please ask.
EDIT: Basically, the professor assigned us to make a game of Uno with a GUI. There can be computer and human players, the numbers of which are determined by the user at the beginning of the game. I coded the entire thing console-based at first to get the core of the game to work, and have since tried to design a GUI; currently this GUI only displays information about the game while it's running, but I'm not sure how to allow the code to wait for and receive input from the GUI without the program charging on ahead. I've investigated other StackOverflow questions like this, this, this, or this, but I cannot comprehend how to apply the answers to my own code. If possible, I'd like an answer similar to the answers in the links (an answer with code I can examine and/or use). I apologize if I sound demanding or uneducated and confusing; I've been working diligently on this project for a couple weeks and it's now due tomorrow, and I've been stressing because I can't advance until I figure this out.
TL;DR - How do I get my main program to wait and listen for a button click event? Should I use modal dialog boxes, or is there some other way to do it? In either case, what code needs to be changed to do it?
Unlike console based programming, that typically has a well defined execution path, GUI apps operate within a event driven environment. Events come in from the outside and you react to them. There are many types of events that might occur, but typically, we're interested in those generate by the user, via mouse clicks and keyboard input.
This changes the way an GUI application works.
For example, you will need to get rid of your while loop, as this is a very dangerous thing to do in a GUI environment, as it will typically "freeze" the application, making it look like your application has hung (in essence it has).
Instead, you would provide a serious of listeners on your UI controls that respond to user input and update some kind of model, that may effect other controls on your UI.
So, to try and answer your question, you kind of don't (wait for user input), the application already is, but you capture that input via listeners and act upon them as required.