I am currently learning java and wanted to give myself a project that was both challenging and fun. I decided to build a game that I remember playing when I was a kid called dopewars.
This is my second attempt at this game. When I began my first attempt, all went well. After a short while my source code began to fill wildly out of control until I could continue no more as I kept getting lost within mountains of code.
I then decided to begin again, only this time I wanted to seperate the gui from the logic (2 different .java files). This is where my problem lies. Previously this would work fine. Since seperating my java files the functionality has stopped.
When I press jbutton b1, my program is supposed to take the price value of cocaine and the units value entered into the jtextfield by the user, perform a calculation by accessing a method within Buy.java, and then update the appropriate JLabels within the s jpanel of GUI.java.
For example, user x wants to buy cocaine at the price indicated, so he enters a value representing the quantity he would like. He then presses the buy button which ultimately deducts the money from his pocket which is shown on the left side of the program window by using a method within the Buy class.
I hope you can understand my explanation and I hope to hear from you soon. Thanks.in advance. My Source code is below.
Maybe you should make a main.java (with GUI, etc.) and a logic.java (or whatever you want to call it) and make the main class Extend the logic class. to solve your jbutton problem, you should probably make the Main class extend the JFrame class, and implement the ActionListener interface, and then in the ActionPreformed method, call a method to do the logic from the logic class. I hope this helped.
Related
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.
First of all I'm new to Java and you'll probably be able to guess. Thanks in advance.
I'm currently writing a board game using Java for an assignment. There are human and computer player classes, and the GUI only in the human player class. In the human class I use a class called 'UI' extending JFrame where the user selects a piece.
At the moment this UI class waits for the enter button to be pressed then sets a 'done' variable to true. In the human player class I create this UI then wait in a while loop continuously checking this boolean before getting the X/Y position of the move.
while (!input.moveEntered());
move.setPosition(input.getX(), input.getY());
This only seems to work if the while loop is not empty. If I add a print statement in there it works fine.
It seems like there is a much better way to go about this. I've looked into dialogs but I don't close the window every time a move is entered.
Thanks for reading.
You should never be busy-waiting; in your case, I would show a modal JDialog. When the user has entered their input, the setVisible(true) method will end without busy-waiting.
Or maybe I misunderstood your problem and you only need to define an event listener in your main JFrame in order to handle user input. Have a look at
http://www.tutorialspoint.com/swing/swing_event_listeners.htm
I was wondering if there was a way to reuse a jframe without making it new. You might be wondering why. I have two JFrames (actually more, but for this question's purpose, two). One contains a radio button(agree) with the terms and conditions written in a jtextarea. THe other JFrame contains a passwordtxtarea(password), jtextarea(username) and a radio button(read terms and conditions), as well as a "TermsAnd Conditions" button.I forgot to mention that the first jtextarea contains a "back" jbutton, that if i press on, I get JFrame2, when I press "Terms And Conditions", I get JFrame1. The problem is, that my code requires both "Agree" and "read the Terms" radio buttons to be clicked on, but whenever I press "back" or "Terms And Conditions", any input I had put in (username, password, clicks on radio button other than default) is lost. Therefore I cannot proceed in my program.
I think it has to do with the fact that I have to make a NEW JFrame Form. Maybe it sets it back to default? Anyway, how do I fix this problem? I haven't seen a question like this, so is there a blatantly obvious answer I'm unable to see, except for "it's impossible"?
You state/and I reply:
I was wondering if there was a way to reuse a jframe without making it new.
Yes, it is quite possible to re-use components (the generalization of your question).
You might be wondering why. I have two JFrames (actually more, but for this question's purpose, two).
As has been stated, this is generally not a goood idea. Most Swing GUI applications use only one main window, the JFrame, and then either swap views such as with CardLayout or JTabbedPane, or show modal or non-modal dialog windows.
One contains a radio button(agree) with the terms and conditions written in a jtextarea. THe other JFrame contains a passwordtxtarea(password), jtextarea(username) and a radio button(read terms and conditions), as well as a "TermsAnd Conditions" button. I forgot to mention that the first jtextarea contains a "back" jbutton,
It's most unusual for a JTextArea to have a button of any kind. Also, there is no such thing as a "passwordtxtarea", perhaps you mean JPasswordField? If so, please be precise with your terms when asking questions here. It's hard enough to guess what someone's program is like based on a description, that you don't want to make it harder on us. Also, it's very unusual to use a JTextArea for a user name field, since usually you'd use a JTextField. Again, precision really matters. Else we'll likely give you the wrong advice.
that if i press on, I get JFrame2, when I press "Terms And Conditions", I get JFrame1. The problem is, that my code requires both "Agree" and "read the Terms" radio buttons to be clicked on, but whenever I press "back" or "Terms And Conditions", any input I had put in (username, password, clicks on radio button other than default) is lost. Therefore I cannot proceed in my program.
Yes, you should not be creating new components here but rather re-using previously created components. It's all do-able if you make your component a class field and if you make sure to create it only once. It's all how you code it.
I think it has to do with the fact that I have to make a NEW JFrame Form. Maybe it sets it back to default? Anyway, how do I fix this problem? I haven't seen a question like this, so is there a blatantly obvious answer I'm unable to see, except for "it's impossible"?
Again it's possible. The solution will all depend on the structure of your program.
A word of advice: gear your GUI code toward making JPanels, not JFrames. This way you can place them anywhere they are needed -- in a JFrame, a JDialog, another JPanel, or swapped with a CardLayout,... anywhere. It greatly increases the flexibility of your program.
I'm building a game using Java for a university project. The game had to use a textual interface at first, and only later we had to add a GUI.
I have a thread running the game logic and updating the game model, and a separate thread, the one with the main function, having the JFrame instantiated on, where I then switch panels according to the game state (the controller tells the gui which frame to display with a setPage method).
Getting the user input, however, is what is driving me crazy now.
With the textual interface, all I had to do to get the user input was to call a method, something like getPlayerNum, and after the user put in the number and pressed enter I would have the input back to the controller.
All the game logic is implemented in a game loop, asking for input when it needs it and notifying the output to the view.
How can I emulate a similar behavior now that I'm forced to use a event-based gui?
How can I block the method call until the user clicks a button, and then have the method return the correct value?
Kudos for developing an independent game model. As a prelude to designing your GUI, start with this very simple game. Add a TextView that listens to the model and reports on game progress. This will help you see how the GUI works, and it may help you decide what additional features you may need in your model.
I am building a graphical user interface in Java and I was wondering if anyone can give me some directions.
Specifically, When clicking on a button in this GUI a big JDialog (it's a class that extends a JDialog) opens up for the user to enter some information, see some information, click on some things etc.
This class has multiple JLabels and other components in it. My question is how would one create such an instance? Right now I have everything in the constructor, making it a 500(!) lines constructor. There has to be an alternative to that!
The constructor is about 300 lines of code of components placement and settings for them and another 200 lines for the listeners give or take.
Also another question that comes in mind is that right now I open this window from another class by calling
MyClassExtendsJDIalog temp = new MyClassExtendsJDIalog();
but I don't use this "temp" variable at all in the class that I create it, as the constructor of "temp" does EVERYTHING. It seems like I am, again, doing something the wrong way.
Thanks for reading this.
If you want split up the code to make it more readable and manageable you can allways group the fields into subclasses of JPanel, i.e. Panel1, Panel2 etc and then just add those in the JDialog subclass constructor. But setting up a GUI in swing takes a lot of lines, yes...
as for the temp variable not being used, I'm guessing you call show() in the constructor?
Normally I would not do that, but instead call it in the code creating the dialog, ie.
MyDialog dialog = new MyDialog();
dialog.setVisible(true);
Without seeing your code it's difficult to give you specific tips on how to improve your code and design.
I agree, ~500 lines in your constructor intuitively feels like a problem. At a minimum, you might want to defer some of that work until after the instance has been created. Moving this into a init() method (or series of methods) is one approach.
You also might want to consider designing your class such that it contains a JDialog instead of extending one (See Composition over inheritance for a discussion on this topic) I suspect otherwise you are conflating the concerns of several classes.
Finally, you might want to review the Java Swing Tutorial for general tips and techniques for creating Swing based user interfaces.
Yes you are doing something wrong, but you are in good (or bad) company.
You should apply the rules of good OO design and clean code to your swing classes as to anything else.
What exactly you can do is hard to tell without looking at the 300+ lines of code (and I really don't want to see the ;-) but here are somethings that are probably applicable.
My main design rule is the Single Responsibilite Principle. According to your description (and my guesswork), you are doing the following in your constructor:
* creating (including configuring) components
* placing them in some kind of layout
* registering Listeners
* implementing Listners
These are 4 completely different concerns.
After some heavy refactoring you might end up with something like this:
You might want to have a factory that creates your components.
You might have a Layouter class that takes a component or a group of components (like label plus matching textbox) and places them on a panel.
You might have a class takes components (and maybe models or whatever) and wires them together using Listeners.
And a class that gets passed all this uses it in a suitable way and spits out a JDialog with the panel with all your components on.
Note: Idealy nothing extends JDialog anymore. You should only extend Janything if you intend to build a new Swing component.
This example is using Scala but it still should offer some inspiration: http://blog.schauderhaft.de/2011/06/26/clean-code-with-swing-and-scala/