Forums Register Login

Getting my main class and GUI components to talk without inner classes

+Pie Number of slices to send: Send
I'm doing the Quiz Card example from Head First Java (p 448-), but to make things interesting, I'm using NetBeans' GUI Builder rather than writing the code myself.

I have a CardBuilderPanel, which extends JPanel and contains text fields and buttons, that I create from my QuizCardBuilder instance, and also a CardBuilderFrame, which extends JFrame and contains menu items.

When I click a button in the panel I need it to send a QuizCard object back to my QuizCardBuilder to store in an ArrayList there. Likewise, I need to call a Save method in QuizCardBuilder when I click a menu item on the frame.

If the frame and panel were inner classes it would be easy, but they're not and I don't think they can be, using the GUI Builder. How do I do it? The frame and panel don't have a reference to the object that created them.

Do I have to create another listener in QuizCardBuilder... if so how, as it doesn't have references to the private components of the panel and frame?
+Pie Number of slices to send: Send
You can always have a reference to the QuizCardBuilder instance in the GUI components and when ever you click on button you can invoke the addToList (supposing this adds the object to the list) method of the QuizCardBuilder instance to add the QuizCard object.

Can you post the code so that we can help you better?
+Pie Number of slices to send: Send
 

You can always have a reference to the QuizCardBuilder instance in the GUI components and when ever you click on button you can invoke the addToList (supposing this adds the object to the list) method of the QuizCardBuilder instance to add the QuizCard object.


But how do I get the reference to the QuizCardBuilder into the GUI components?

If you have a class Foo that creates a Bar, then your Foo can access the Bar's methods with bar.doSomething(), but if your Bar reacts to an event and wants to call back the Foo that created it, how does it do it?

Here are what the components look like + the code. I don't include all the generated stuff because it's too long.

The CardBuilderFrame:


The CardBuilderPanel:









As it is, for some reason the CardBuilderPanel is not displayed in the CardBuilderFrame. I don't know why. I just see the frame. If I replace the CardBuilderFrame in QuizCardBuilder with a regular JFrame, it displays the panel.

Do I have to make the CardBuilderPanel a instance variable of the CardBuilderFrame?

If I did that I could store the QuizCards in a List in the CardBuilderPanel (as I have above), and also add a save method to the panel, which can be called by the frame when the Save menu item is clicked.

I guess this approach would work, but I end up having all my application logic within my CardBuilderPanel class. It doesn't seem right to do it like this, because I just want to keep my GUI classes doing GUI things like displaying text fields, rather than being the application itself. It can't be normal to have a whole application that is an extension of JFrame?
+Pie Number of slices to send: Send
I managed to get the panel to display... I changed the frame layout to BorderLayout...
+Pie Number of slices to send: Send
Well, I have my version of the QuizCard app up and running now, including a Viewer frame / panel, but with all the code within the panel and frame class files.

I guess what I wanted to do is to put the listeners in the QuizCardBuilder class. All this class does at the moment is to call up a new frame and display it, while the frame and panel take care of all the logic.

I could implement this by adding accessor methods to the buttons and menu items, then put listeners in QuizCardBuilder using

but this seems a bit long-winded.
+Pie Number of slices to send: Send
You can make QuizCardBuilder as an instance variable in CardBuilderFrame and in all the action listeners you can use the QuizCardBuilder instance to invoke the methods.
+Pie Number of slices to send: Send
But if the QuizCardBuilder is a variable of the CardBuilderFrame, how do I invoke its methods from the buttons on the CardBuilderPanel? I need to use both the menu items in the frame and the buttons and text fields on the panel.
+Pie Number of slices to send: Send
 

Luigi Plinge wrote:But if the QuizCardBuilder is a variable of the CardBuilderFrame, how do I invoke its methods from the buttons on the CardBuilderPanel? I need to use both the menu items in the frame and the buttons and text fields on the panel.



Then you can make it part of both the components.
+Pie Number of slices to send: Send
But it will then be 2 different instances, so if I try to use a method to save it from the frame, it won't contain the questions/answers that have been added on the panel.

Plus it doesn't make sense to have it as an instance variable. QuizCardBuilder is the application itself and creates the frame and panel - it doesn't belong to the frame or panel.
+Pie Number of slices to send: Send
 

Luigi Plinge wrote:But it will then be 2 different instances, so if I try to use a method to save it from the frame, it won't contain the questions/answers that have been added on the panel.

Plus it doesn't make sense to have it as an instance variable. QuizCardBuilder is the application itself and creates the frame and panel - it doesn't belong to the frame or panel.



You are creating the Frame and panel objects at the same time. While you are creating it- You can pass a reference to QuizCardBuilder
+Pie Number of slices to send: Send
Good idea!

I could invoke instantiate the frame with

and then use it as an instance variable in the frame and panel.

Is this a standard way of doing things? I haven't seen it before.
+Pie Number of slices to send: Send
I dont know if its a standard or not. But usually if you see the MVC architecture- You would have Controller Classes which respond to the actions from the UI and Model classes which actually represent the data you are working with. In your case- You have the View classes- JFrame, JPanel and then one class which has methods which respond to different actions and these methods then work on the data you have created during the response to the action.
+Pie Number of slices to send: Send
If anyone's interested, I got a bunch of instances running in different threads all talking to each other using the method suggested above, giving the output

After 0.1 seconds, Controller #1 calls Jemaine
After 0.4 seconds, Brahbra calls Murray
...Murray explodes!
After 0.4 seconds, Murray calls Bret
After 0.9 seconds, Murray calls Brahbra
...Brahbra explodes!
After 1.1 seconds, Brahbra calls Jemaine
After 1.1 seconds, Controller #2 calls Bret
After 1.3 seconds, Bret calls Brahbra
...Brahbra explodes!
After 1.4 seconds, Murray calls Bret
After 1.9 seconds, Jemaine calls Murray
...Murray explodes!
After 2.0 seconds, Controller #1 calls Murray
...Murray explodes!
After 2.1 seconds, Controller #2 calls Bret
After 2.4 seconds, Bret calls Controller #2
After 2.7 seconds, Brahbra calls Jemaine
After 2.9 seconds, Murray calls Brahbra
...Brahbra explodes!
After 3.1 seconds, Murray calls Controller #1


etc.

Each instance calls another instance, which calls the first back to get its ID. The different classes can react in different ways to being called, like exploding.

They don't have to be the same class. In this example I set up an interface and extended an abstract class to save having to re-implement the same methods, but you don't need to and could do it on a class by class basis by overloading the "link" method. (I suspect generics could come in handy but I haven't read up on those yet.)







I got this tall by not having enough crisco in my diet as a kid. This ad looks like it had plenty of shortening:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com


reply
reply
This thread has been viewed 1716 times.
Similar Threads
Class instantiation within the same class
Replacing GUI with new GUI
Can't Focus On JPanel
Dynamic Swing Components
Question about GUI (with NetBeans IDE)
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 19, 2024 04:52:38.