• 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 Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

Help with actionlisteners on a button.

 
Ranch Hand
Posts: 51
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am a new programmer and not quite sure what to do to register a button click, i know about action listeners but they dont make much sense the way some the oracle website explains it. Below is my code.






Note: I have tried to do action listeners but havent been able to get it, I sense I'm missing something quite simple.
 
Bartender
Posts: 825
5
Python Ruby Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Did you read Writing Event Listeners tutorial and if you did what specific part of it you didn't understand?

When writing your own listeners, there are couple of steps you should follow (which you did to some point). In your case your listener is implementing ActionListener interface which declares one method:

To register the listener you defined to component that should handle the event using it, you write:

Whenever user clicks myButton, that object creates ActionEvent object and calls actionPerformed() method of listener registered to it to handle the event.

Now, to review your code. What I first noticed in your code is that your listener class (DataEvent) is abstract, which means you can't instantiate it hence you can't register it to your button. If you change the class signature not to be abstract, you still didn't register your listener to the button in your gui, so the action you implemented will never get executed.
As for the approach you have chosen, you have reference to DataApplication in your listener. But you didn't initialize it, nor you provided the constructor to do that, so it's always null. Hence, if you change the code as I stated above, the click on button will be handled, but you'll get NullPointerException.
 
John Corkrend
Ranch Hand
Posts: 51
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So all I do is take out abstract and add a listener for my button? And how do I initialize what you said? Also is it ok to use the string command to determine if a button was hit.
 
Marshal
Posts: 79969
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

John Corkrend wrote: . . . Also is it ok to use the string command to determine if a button was hit.

No, no, no, no, no.

Don’t use one actionPerformed method, nor allow a Component to implement ActionListener.

Create a class for each sort of action you want (which should, by the way, be called XYZListener) and add that to each button.Sorry, but I haven’t the time to expand on that.
 
John Corkrend
Ranch Hand
Posts: 51
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok now I'm confused now about the different classes. You want me to have one for the GUI, listeners, and events.
Could somebody clarify this, the book I'm learning from did this a different way.

And if somebody could please provide me with the right code for DataEvent the COMPLETE code.
 
Campbell Ritchie
Marshal
Posts: 79969
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If a book uses addActionListener(this) frequently, then it belongs in the recycling.
You should change the name of the class, and get rid of the if bit:Note all classes should have a constructor. You would have had trouble with your empty constructor; that would have caused null values and Exceptions. Also it ought not to be abstract.
You should have the done button in the data application given private access, and a get method to provide access in other classes. That is unnecessary if you have it as a private inner class (i.e. inside the data application class), when you can reduce it to this:You can add it like thisI think you should go through your code carefully, looking at all the names of the classes and fields, because I think their names could be improved.
 
Campbell Ritchie
Marshal
Posts: 79969
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I seem to fulminate about addActionListener(this) every now and again, usually referring back to my old threads. Try here here and here for more information. You may end up with the same old thread referenced several times.
 
John Corkrend
Ranch Hand
Posts: 51
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok why does every class need a constructor?

And why does it need to be given private access?
 
Campbell Ritchie
Marshal
Posts: 79969
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Constructors are used to enable instantiation of the class, and to restrict instantiation of the class. If it is a private inner class, you want to restrict knowledge about it to inside the class (that means inside the outer class), so I thought it ought to have a private constructor. That restricts instantiation (at least I think it does) to inside the class which means inside the outer class. A private constructor will achieve that and you can still access the button with private access, because they are inside the same class (or even the same method). By inside the same class, I mean inside the outer class.
If you don’t supply a constructor, then the compiler will add one for itself, which might not necessarily do what you intended. That is called a default constructor. It is one of those things which the compiler will allow, but which is not regarded as good style.
I think it would work if you gave the constructor other access in the inner class. If you have a standalone public class, then the compiler would usually have public access.
 
John Corkrend
Ranch Hand
Posts: 51
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, I've made changes to the code but get an error "doneButton cannot be resolved."






 
Kemal Sokolovic
Bartender
Posts: 825
5
Python Ruby Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
And the error says clearly what the problem is. Your listener is a separate class, and you are trying to use doneButton as if it's declared, though it's not.

You should check ActionEvent#getSource() (actually it's inherited from EventObject) method in the API. That one gives you the possibility to get an object on which the event occurred.
 
John Corkrend
Ranch Hand
Posts: 51
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So what exactly do I do? Where do I add the listener or declare it.
 
Kemal Sokolovic
Bartender
Posts: 825
5
Python Ruby Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you keep your implementation, you would get the object on which the event occurred in method you already have:


Or, since that listener is rather trivial, you can use anonymous listener, which you would define in DataApplication class:
 
John Corkrend
Ranch Hand
Posts: 51
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, so just to make sure I understand this code right

If the button is pushed it goes to this class and to actionPerformed and does whatever it says, right?

And also what does this line do?
 
Kemal Sokolovic
Bartender
Posts: 825
5
Python Ruby Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

If the button is pushed it goes to this class and to actionPerformed and does whatever it says, right?


If the button is pushed (an event has occurred) the listener registered to that button reacts on that event. In case of your classes, if you register your listener to doneButton:

then the code inside actionPerformed(...) method of DataEventListener class will be executed.

The line that you're asking about is getting the object on which the event has occurred (read the API). So with getSource() you get an Object instance which is actually an object that "triggered" the event. Since you know it's JButton in your case, you cast it so you can invoke setEnable(false) on it. So basically, with that line you are getting a reference to JButton that was clicked.
 
John Corkrend
Ranch Hand
Posts: 51
Eclipse IDE Chrome Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok thanks a lot, that solved my problem. But i want to know whats considered better, having the event handled immediately inside the same class or going to different class to handle the event. So like I have it right now where it goes to a different class, or like this one.
 
Kemal Sokolovic
Bartender
Posts: 825
5
Python Ruby Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That depends on some properties of the listener. For example, when the listener is that simple that it contains one line of code, I do it by creating an anonymous inner class:

You may also want to put the action code in a separate method (even if it's just a couple of lines of code), especially when you use the same listener for more than one component, but you also want to have access to some other fields of the class where you define it:


In other cases, like when you have a lot of components in your GUI, many of them have common listeners, or when you insist following some design principles then it would appropriate to have a listener defined in a separate class.
 
Can't .... do .... plaid .... So I did this tiny ad instead:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic