permaculture playing cards*
The moose likes Swing / AWT / SWT and the fly likes Help with actionlisteners on a button. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Help with actionlisteners on a button." Watch "Help with actionlisteners on a button." New topic
Author

Help with actionlisteners on a button.

John Corkrend
Ranch Hand

Joined: Oct 27, 2012
Posts: 51

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.
Kemal Sokolovic
Bartender

Joined: Jun 19, 2010
Posts: 825
    
    5

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.


The quieter you are, the more you are able to hear.
John Corkrend
Ranch Hand

Joined: Oct 27, 2012
Posts: 51

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.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39834
    
  28
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

Joined: Oct 27, 2012
Posts: 51

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
Sheriff

Joined: Oct 13, 2005
Posts: 39834
    
  28
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
Sheriff

Joined: Oct 13, 2005
Posts: 39834
    
  28
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

Joined: Oct 27, 2012
Posts: 51

Ok why does every class need a constructor?

And why does it need to be given private access?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39834
    
  28
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

Joined: Oct 27, 2012
Posts: 51

Ok, I've made changes to the code but get an error "doneButton cannot be resolved."






Kemal Sokolovic
Bartender

Joined: Jun 19, 2010
Posts: 825
    
    5

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

Joined: Oct 27, 2012
Posts: 51

So what exactly do I do? Where do I add the listener or declare it.
Kemal Sokolovic
Bartender

Joined: Jun 19, 2010
Posts: 825
    
    5

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

Joined: Oct 27, 2012
Posts: 51

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

Joined: Jun 19, 2010
Posts: 825
    
    5

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

Joined: Oct 27, 2012
Posts: 51

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

Joined: Jun 19, 2010
Posts: 825
    
    5

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.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Help with actionlisteners on a button.