Win a copy of Transfer Learning for Natural Language Processing (MEAP) this week in the Artificial Intelligence and Machine Learning forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Paul Clapham
  • Devaka Cooray
  • Bear Bibeault
Sheriffs:
  • Junilu Lacar
  • Knute Snortum
  • Liutauras Vilda
Saloon Keepers:
  • Ron McLeod
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Piet Souris
Bartenders:
  • salvin francis
  • Carey Brown
  • Frits Walraven

How to detect if a action listener has been triggered from another class?

 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have a method which asks the user a question and in my GUI I have a JTextArea where they type in the answer. How do I get the method (that is asking the question) to get the value of the JTextField once the user has typed something into the value? I have a action listener I am just unsure what to put in it to get this working


GUIPanel (JPanel class):


I have not yet added the method call yet but basically it will call a method which will ask a question and then the user has to answer. This is what I am stuck on. I do not know how I can get the method to "detect" that the user has entered something and then retrieve the data.

I thought about making the textfield static and making a static boolean which gets changed to true when the action performed (user presses enter) gets triggered but that would mean the method would have to have a while loop to check so there must be a better way out there. Sorry for all this, very new to GUI/Swing.
 
Sheriff
Posts: 15519
263
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You don't. It depends on how you're asking the user. If it's via a modal dialog, like what this tutorial about creating dialogs shows, you'll get the answer as a return value. If the user has to enter the answer into a text field and then click a "Submit" button, then you'd have an ActionListener on the submit button and then get the value of the answer from the text field.
 
Junilu Lacar
Sheriff
Posts: 15519
263
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here's another tutorial https://docs.oracle.com/javase/tutorial/uiswing/components/textfield.html -- this shows examples of when you'd want to add an ActionListener on a text field. I don't think you want that for your particular use case though. You want to wait until the user enters their full answer before doing anything with it, not while they're still in the middle of typing the answer in.
 
Dale Viljoen
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Junilu Lacar wrote:You don't. It depends on how you're asking the user. If it's via a modal dialog, like what this tutorial about creating dialogs shows, you'll get the answer as a return value. If the user has to enter the answer into a text field and then click a "Submit" button, then you'd have an ActionListener on the submit button and then get the value of the answer from the text field.



I am asking the user via the TextArea (have not figured out (yet) how to direct output, for the methods in other classes, to the GUI TextArea). I am unable to do dialogs as we have not been taught that and want us to stay within what we have been taught. Now, in terms of the submit button having a action listener. I had that idea but here is the part were I get stuck. Method from class A asks question, user inputs answer into GUI in class B. How do I get the users answer from class B to class A?
 
Marshal
Posts: 25436
65
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, for your example I don't see why you need two separate classes. There's no reason to have a class which extends JPanel; the class you posted doesn't override JPanel in any way. So you could perfectly well include all of its code in your GUI class. Which, by the way, doesn't override JFrame in any way so it shouldn't extend JFrame either. Just create a JFrame in your GUI class and work with it.

After you do that you'll find that you only have one class and your problem goes away.

There are certainly ways to communicate between two objects (not "between two classes" as you think) but it's better to avoid that until you've studied object-oriented design a bit more.
 
Dale Viljoen
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Paul Clapham wrote:Well, for your example I don't see why you need two separate classes. There's no reason to have a class which extends JPanel; the class you posted doesn't override JPanel in any way. So you could perfectly well include all of its code in your GUI class. Which, by the way, doesn't override JFrame in any way so it shouldn't extend JFrame either. Just create a JFrame in your GUI class and work with it.

After you do that you'll find that you only have one class and your problem goes away.

There are certainly ways to communicate between two objects (not "between two classes" as you think) but it's better to avoid that until you've studied object-oriented design a bit more.



Let me give you an example of what my program holds in terms of classes. So I have the two GUI classes and a example of some of my other classes are Player, Teacher, Location, Suspect and so on. The teacher class holds a method called introduction lines and in that method the teacher talks to the player. Telling them how the game works etc. Once the teacher is done talking he asks for the players name. Here is where I want to take what the player has inputted from JTextField and return that value back to the teacher class. The name the player has chosen will be used to make a Player class.

That is what I am stuck with. How do I get the players name from the text field to the Teacher class? Also I just wanted to say thank you so much for your help, as you can tell this is all new for me and others have not been as forgiving.

Lastly, just to double check. You are saying its best to make one GUI class that holds the JFrame and JPanel as we do not actually override any methods? If that is what you are saying, it makes perfect sense. However, my lecturer said we will lose marks if we have all the GUI in one class. What I have done with extending was how we were taught so I am not sure why he would tell us to do it that way.
 
Dale Viljoen
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just gave everyone here a like for all their help. I have been a long time lurker on this site and decided to join here instead of other communities as it seemed a lot more forgiving to new programmers. Thank you everyone!
 
Marshal
Posts: 68909
275
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

As Paul has already mentioned, you shouldn't extend most GUI classes. Your GUI ISN'T A frame, but is HAS A frame. This is the sort of thing you should write:-You needn't use setResizable(true) nor frame.setLayout(new BorderLayout()); because the frame already has those two attributes in its default state. Write setVisible(...) in a separate method like likes 12‑15. Line 1 is a strange‑looking formula to start the correct threading for Swing applications. Write that as the body of the main() method. Methods called from the constructor (line 17) should always be marked private or final, but it isn's necessary to use both modifiers.

I think you have misunderstood what you were told about number of classes. You should have the game logic in a game class, and that logic can be accessed via the command line/terminal with doSomething() methods and getSomething() methods. You fire the actions from your GUI by calling a doSomething() method and you get the result by calling a getSomething() method.I think the game object should pass the information on to the Teacher object and Player objects. Does that give you any ideas about what you are looking for? Obviously your game class, whatever that is, will use objects from other classes, so you are now using multiple classes. I suggest you go back to what you were told and seek more explanation from your teacher. You want to make sure you have understood the question correctly. Ask in public in case somebody else has the same misconception and daren't ask.
 
Paul Clapham
Marshal
Posts: 25436
65
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Like I said before, you don't pass data from one class to another. You pass data from one object to another.

So for example if you have a GUI object and you want to pass a String to that object, then it should provide a method whereby it can receive that object. Like so:



So your GUIPanel object is going to have to call that method on the GUI object.

(I called the method "setTypeHere" because that's all I can tell about the use of the field in question. Your variable names are pretty un-explanatory. You probably know what the field is for.)

 
Dale Viljoen
Greenhorn
Posts: 8
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you for the help Campbell and the others , you have really helped me understand how I should be setting up GUI classes as we were not taught this way. I also personally find this method a lot easier and makes a lot more sense. I will go ahead and ask publicly so the rest of the students can see in case others are stuck with the same idea. He did mention it in a lecture so a few individuals might of missed it.

the submitAnswer() method you have created is really great and passing the label through as a parameter for the method allows me to access the JTextField value from another object (in my case, Teacher object) so thank you for that.

What I am needing, is once the user hits enter button (after writing their answer) then the action listener for that button essentially gives the answer back to the Teacher class and this is where I am stuck on.

So (just for example) this is the method inside Teacher and is called by the GUI class:



Firstly, do not worry about the System.out.println as I will later on figure on how to redirect output to the JTextArea instead. But how do I get the method to "wait" for the user to trigger the action listener and return the value back to the introduction() method? Or is that not possible?

The only thing I can think of, is to have two methods. One that introduces the students and when it asks for the name the method finishes. Once the student writes their name into the JTextField and triggers the action listener then have the action listener call a method (that is in Teacher object) called SetTypeHere(String typeHere) where the JTextField value is passed through and then have that method call the second introduction2() method which carries on the game now with the created Player class which was created with the inputted name.

Thank you for the trouble everyone has gone through on this, It is really nice of you all!
 
Paul Clapham
Marshal
Posts: 25436
65
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Dale Viljoen wrote:But how do I get the method to "wait" for the user to trigger the action listener and return the value back to the introduction() method? Or is that not possible?



It's not possible, and it's not meaningful to ask that anyway. In a Swing application, after you construct the GUI and call its setVisible(true) method, Swing is in charge. It waits for the user to do things to the GUI, like typing in text fields and clicking on buttons. When the user does certain things, Swing calls your action listeners and other similar methods. The purpose of your code is simply to react to those events.
 
Dale Viljoen
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Paul Clapham wrote:

Dale Viljoen wrote:But how do I get the method to "wait" for the user to trigger the action listener and return the value back to the introduction() method? Or is that not possible?



It's not possible, and it's not meaningful to ask that anyway. In a Swing application, after you construct the GUI and call its setVisible(true) method, Swing is in charge. It waits for the user to do things to the GUI, like typing in text fields and clicking on buttons. When the user does certain things, Swing calls your action listeners and other similar methods. The purpose of your code is simply to react to those events.



Would my idea that I listed work out fine or is not impossible? So if this is all not possible, then how exactly do programmers deal with this situation. How do I have my teacher class ask the user a question because as you said it is impossible? I just want to know how it would I can do it as I have already finished my program and just currently developing a GUI for it (we had to develop the CUI version first for the assignment).
 
Junilu Lacar
Sheriff
Posts: 15519
263
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You have to recognize that the flow of control and execution in a GUI program is very different from that of a CUI program. In a CUI program, you can literally trace the flow of execution with your finger, going through each line in the source code sequentially. In an event-based GUI, however, flow is dependent on runtime events, so you have to use your imagination a little bit more to insert simulations of those events as you read through your code.

So you have to think things like "Imagine the user typed in his/her name in this text field. Then they click on the submit button." The "click on the submit button" is the event that you've just inserted into the flow that you're trying to simulate with your imagination.

Basically, there are two things you can do in your situation: either actively push the value to the other class the way Paul described earlier or you can have the Teacher "pull" the information from the Player. By pull, I mean something like this: when the name is entered, it's just stored somewhere, say in the Player itself. The next time the Teacher object does something, it just calls a method on the Player that returns the name that was entered previously. This implies that the Teacher has a reference to the Player object, so that it can ask Player for the name.

In the other scenario, you have a "push": The name is entered and when the submit button is clicked, a method on the Teacher is called to say "here's the name that was entered." The Teacher can then do whatever it needs to do with the value that was just pushed to it.
 
Campbell Ritchie
Marshal
Posts: 68909
275
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Dale Viljoen wrote:Thank you for the help Campbell and the others . . .

That's a pleasure

So (just for example) this is the method inside Teacher and is called by the GUI class:

Methods aren't called by classes. They are called by the flow of execution in other methods in what Junilu called CUI programs, and by an event caused by a user action in a GUI program. The event in a GUI usually causes a method to be called.

. . .

Please avoid such long comments; either break them into multiple lines as /* comments */, or write them in the text something like, “Line 4 should get the player's name....” Otherwise the long lines fall off the edge of the reader's screen and become illegible. Line 4 is, I am afraid, not compatible with an app you want to put a GUI on top of. What you want is a Game class (or similar) and a GameDemo class. This sort of code belongs in the GameDemo class.That would have a counterpart in a GUI app like this:-which you can abbreviate to this:-Notice you are using the same method in the game object. A Scanner will block execution until the <enter> key is pressed. A Swing application will not execute anything until an event occurs which is captured by the appropriate listener.

For more information about writing action listeners as λs look at the Java™ Tutorials.
 
Dale Viljoen
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Junila, thank you for all of that. I finally understand this whole GUI and the order of execution and the two methods you have given me are brilliant and I definitely will be using one of those. You all have given me many ideas now to work with my program and I will definitely changes things up a lot now. I have no clue when I would of figured this stuff out had I not asked here!
 
Dale Viljoen
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Wonderful, I will remember that in the future in terms of long comments! Thank you for all of the help, bettering my coding practices Lastly, why does one have to put "evt ->" when adding action listener?
 
Paul Clapham
Marshal
Posts: 25436
65
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Dale Viljoen wrote:Lastly, why does one have to put "evt ->" when adding action listener?



The action listener code you're asking about is a method whose signature is void actionPerformed​(ActionEvent evt). So you'll see that it takes a parameter (which is an ActionEvent reference). You may or may not need to use any data from that ActionEvent, but nevertheless you have to declare the parameter in the lambda code. That's what it is. But all you need to know is that a certain button was clicked, and you know that because the action listener is attached to the certain button. so you don't need to use the parameter in your present version of the application. But like I said, you still need to declare it.
 
I'm thinking about a new battle cry. Maybe "Not in the face! Not in the face!" Any thoughts tiny ad?
Two software engineers solve most of the world's problems in one K&R sized book
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
    Bookmark Topic Watch Topic
  • New Topic