| Author |
Interaction between GUI class and "main" class
|
Karl Svensson
Greenhorn
Joined: Jan 26, 2006
Posts: 9
|
|
Hello. I guess this is a very basic question. But, that's why I'm posting it in the beginners section... I have written a simple game that asks questions to which the user answers by pressing buttons. I have put all the GUI stuff in a separate class and everything else in another class (let's call it the "main class"). The main class' responsibility is to (a) read all the questions from a file and (b) determine which question to display, by randomly selecting a question which has not yet been displayed. My problem is to know WHEN to display a new question. I start the main class by creating an instance of the GUI class, and telling this instance to display a random question, but what happens next? The actionlisteners are in the GUI class, and I can't figure out how to get the main class to know when the user has pressed a button. I guess I should send some message from the actionPerformed method to the main class, but what would this look like, and how should I implement the "actionPerformed listener" in the main class? I'm not asking for code examples but just some input on how this could be done. Any help would be appreciated.
|
 |
Karl Svensson
Greenhorn
Joined: Jan 26, 2006
Posts: 9
|
|
OK, I have now managed to "solve" the problem, but it's a very bad solution (I guess) and I hope someone can give me advice so I can improve it... This is the methods I have in the main class: * generateAndShowNewQuestion() Selects a question randomly and tells the GUI to show it. * checkAnswer(String x) Checks whether the given answer is right or wrong and displays an appropriate message. This method is called from the actionPerformed method in the GUI class. My solution was to introduce a static boolean variable, "answered", which is set to "true" in the checkAnswer method. Now my main method looks like this: So, the program shows a question and then stays in the "while(!answered);" loop until the checkAnswer() method is called. While it works, I feel there might be a better way to do this..?
|
 |
Justin Fox
Ranch Hand
Joined: Jan 24, 2006
Posts: 802
|
|
well, your "main class" needs to be a JFrame, to display the GUI, the ActionListener should be assigned to the button of you choice and know when the button has been pushed. what you could do is have a JTextfield, and when the button is pushed, do the JTextfield.getText(); and then compare it in an if statement. ok, this program must be for school, cause its rediculous. what your doin works, so leave it that way. the only other way i would know to generate the question better. would to have an object array , that stores the questions you want. then you have a randomgenerator that generates a number 0 - array.lenght-1. then you use that randomn number to call the index of the object array. and display it. sounds long, but it would shorten up your code.. well, i hope this kinda helps Monk..
|
You down with OOP? Yeah you know me!
|
 |
Karl Svensson
Greenhorn
Joined: Jan 26, 2006
Posts: 9
|
|
Thank you for reply...
Originally posted by Monk Fox: well, your "main class" needs to be a JFrame, to display the GUI,
My GUI class is a JFrame. That is not the problem.
It already is.
what you could do is have a JTextfield, and when the button is pushed, do the JTextfield.getText(); and then compare it in an if statement.
No, because each question has a number of alternatives. But this has nothing to do with my problem.
ok, this program must be for school, cause its rediculous.
No, it's not for school. I am learning Java on my own. Why do you think it's "rediculous" (sic)?
what your doin works, so leave it that way.
Thank you, I know that it works. But I was curious to know if someone had a better solution, because staying in a "while" loop didn't feel right...
the only other way i would know to generate the question better. would to have an object array , that stores the questions you want. then you have a randomgenerator that generates a number 0 - array.lenght-1. then you use that randomn number to call the index of the object array. and display it.
Yes, I have already implemented the question generator that way. But this has nothing to do with my problem.
well, i hope this kinda helps
Well, I don't know if it kinda helped. But thanks anyway.
|
 |
Ernest Friedman-Hill
author and iconoclast
Marshal
Joined: Jul 08, 2003
Posts: 24061
|
|
Originally posted by Monk Fox: ok, this program must be for school, cause its rediculous.
Monk, remember that the number one rule of JavaRanch is Be Nice. This isn't a nice thing to say, nor is your response very helpful. You've had a lot to say without actually speaking to the question that was asked. Now, Karl: perhaps without knowing it, you've wandered into Multithreaded Programming Territory. main() runs in one thread, and GUI events are handled in another. You're wondering about how to communicate between them, and you've come up with a workable scheme (if not an optimal one.) Congratulations! Here lies power, but also responsibility. You need to make sure you understand what you're doing, but if you do, you can do neat stuff. First, I'm going to show you the "right" way to do the waiting that you're already doing; then I'm going to talk about other approaches. First: instead of the "busy-wait" in main, you can use the wait() and notify() methods in Object. Sun's threading tutorial will teach you all you need to know. Basically, main() would call wait(), where it would simply stop; and the event handler would call notify(), which would let main() proceed. None of the excess CPU time usage you're now seeing would happen. Now: you've got code in main() running on one thread, and code in your GUI running on another, and so in your mind, threads and classes are intertwined a bit. Let me point out, though, that they're not, necessarily, and that the following plan lets you avoid the commnunication between threads, but still separate the question-management code into one class, and the GUI into another: 1) In your main class, you'd have methods to -- Load questions: void loadQuestions() -- choose a question: String getNextQuestion() -- "grade" a question: boolean isRightAnswer(String question, String answer) 2) In your GUI class, you'd have all the setup code and event handlers. 3) main() would create a GUI instance and display it, perhaps with an initial question. Note that the GUI class can have a member variable that holds an instance of the main class, and the main class can pass an instance to the GUI class as a constructor argument. The GUI class can then use that member variable to call non-static methods on the main class. 4) (Here's the really new part) The event handler for the "accept my answer" button would call main.isRightAnswer(), and either get the next question by calling main.getNextQuestion() or not, depending on the return value. Note that once the initial GUI is set up, the thread executing main() can terminate -- control is now handed over to the event-handling thread. But all the code that knows about the list of questions is in the main class, still, and the GUI can still use it. Does this all make sense?
|
[Jess in Action][AskingGoodQuestions]
|
 |
Stan James
(instanceof Sidekick)
Ranch Hand
Joined: Jan 29, 2003
Posts: 8791
|
|
Let events on the GUI drive everything. It's common to structure three objects here: View is the Swing page, Controller interprets events from the UI into some action and tells the UI what to do, and Model holds the data for the application. Your "main" right now is a bit of both. See if this works for you: [ March 01, 2006: Message edited by: Stan James ]
|
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
|
 |
marc weber
Sheriff
Joined: Aug 31, 2004
Posts: 11343
|
|
|
For an example of the Model View Controller (MVC) pattern outlined above, see building GUIs with the MVC pattern.
|
"We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer
sscce.org
|
 |
Karl Svensson
Greenhorn
Joined: Jan 26, 2006
Posts: 9
|
|
Thank you, Ernest and Stan, for your very helpful answers, and Marc for the link. I am happy to say that I have now gotten the whole thing to work without any CPU intensive "while" loops. I chose the second approach that Ernest described, i.e. sending an instance of the main class as an argument to the GUI constructor, and then calling isRightAnswer from the actionPerformed method. This required lots of rewriting, but it finally worked and I also think that I understand what is happening. Once again, thank you very much.
|
 |
 |
|
|
subject: Interaction between GUI class and "main" class
|
|
|