My class implements ActionListener. I have implemented the following nested classes below:
JMenuItem mntmNew = new JMenuItem("New...");
mntmNew.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
doNew(e); //calls to outer class for cleaner code
}
});
mnFile.add(mntmNew);
JMenuItem mntmLoad = new JMenuItem("Load...");
mntmLoad.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
doLoad(e); //calls to outer class for cleaner code
}
});
mnFile.add(mntmLoad);
//etc. for the rest of the menu system
However, Eclipse is still telling me that my class must implement the inherited abstract method ActionListener.actionPerformed(ActionEvent e). Can you not implement override methods in a nested class in this way?
Your question:
Can you not implement override methods in a nested class in this way?
The answer is no. Eclipse (actually Java) is complaining that while you're declaring your class as implementing ActionListener you're not giving your class the necessary actionPerformed(...) method in the class's own scope -- and this last part is very important. The class that implements the interface must implement all the interface's required methods in its own scope and not in nested classes. Note that this doesn't prevent you from nesting classes that also implement ActionListener or other interfaces, but regardless, the rule remains that a non-abstract class that implements an interface must override all of the interface's methods.
But since you're not using objects of your class as an ActionListener, the simple solution is to not declare your class as implementing the ActionListener interface. Problem solved. And actually you're far better off not having your GUI class implement your listener interfaces since combining them in one class is asking a class to do too much. In technical terms, it unnecessarily reduces a class's cohesion and risks increasing it's coupling reducing its readability and maintainability.
Related
I will illustrate my issue with the use of an example:
The addActionListener method accepts an ActionListener Interface as its only argument.
So when invoking that method on an object/component (such as a Button) in order to register a listener to the object, through the use of an anonymous inner class, why is it that we also need to implement the Interface class? Is it because by definition, interfaces cannot be instantiated, unless of course you are creating an object of that Interface type that implements the abstract methods of that Interface?
i.e.
aButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// do stuff
}
});
That is, through the use of anonymous classes, we can avoid explicitly making the entire class implementing the interface (as declared in the header), but rather we are instantiating an object of the Interface (which by definition of an Interface shouldn't be possible) and implementing the Interface's abstract methods within the anonymous class.
So it is only possible to instantiate an object the Interface due to the fact that at that point in time, a contract needs to be fulfilled to implement the Interface's methods, and in doing so, allows us to make an object from the Interface?
Therefore, is the reason why we can implement the actionPerformed() method of the Interface only possible because of the fact that we had instantiated an object from the Interface (which simultaneously requires us to fulfil the contract of implementing the abstract methods)? So could it be said that we are 'implicitly' implementing an interface by the in-situ instantiation of the Interface (as the addActionListener argument)?
You are not instantiating the interface.
You are defining and instantiating an actual, concrete class that implements the interface. You need to implement every method declared in the interface, just as if you wrote a "normal" class implementing the interface.
The anonymous class construct saves you the trouble of having to name a class that is only going to be used in one very specific place in your code. But if you wanted to you could have decided to do that. Under the covers it is the same thing -- you have defined a class to implement the interface and then instantiated that class.
I'm new at Java and I have started out with a tutorial... The tutorial wants you to start this way:
package proj;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Proj extends JFrame implements ActionListener {
public static void main(String[] args) {
}
}
But I get an error message on the class Proj, that is saying: "Proj is not abstract and does not override abstract method actionPerformed(ActionEvent) in ActionListener".
I don't quite understand what this error message means, and in the tutorial this isn't mentioned.
Your class Proj implements an interface. An interface can "tell" which methods a class, implementing this interface, has to implement. The ActionListener interface guarantees that a class implementing this interface has also to implement said method actionPerformed(...). So in order to fix this: Implement said method.
No offense, but: You might want to take a look into some Java starter tutorials or books.
ActionListener is an Interface containing the method actionPerformed(ActionEvent e). When you implement an interface, you agree to create an implementation of all methods declared in said interface.
You have not implemented the actionPerformed(ActionEvent e) method that's in the interface you told the Java compiler you would implement, hence the error. You also have to make sure to use the same modifiers for the method as in the interface, in this case public void.
I suspect the tutorial you are following will get to this, you probably just tried to compile the program prematurely. If not, I'd send an email to the owner of the tutorial!
If a class implements a interface, it should implement all the method in that interface, unless it's an abstract class
ActionListener is an interface in Java, and your class Proj is not an abstract class, so You must implement actionPerformed(ActionEvent e) method appropriately defined in that interface.
You need to override the actionPerformed method.
ActionListener is a interface. Interfaces declares methods, but don't include its body. When you implement a interface you should provide a body for inherited method or declare it as abstract (saying: hey! my subclass should implement it).
Just add the missing method for ActionListner interface.
I am trying to teach myself Java and had a question that I wasn't able to answer so far. In some of my reading online I have found two ways of using action listener that seem to do the same thing. But I am trying to figure out what is the advantage/disadvantage of one over the other.
Is it better to use anonymous class like this:
public MyClass() {
...
myButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
//doSomething
}
});
...
}
or is it best to implement at the beginning of the class like so:
public MyClass() implements ActionListener {
...
myButton.addActionListener(this);
public void actionPerformed(ActionEvent e) {
//doSomething
}
...
}
Only if your class really is an ActionListener (is-a relationship) and will be used as an ActionListener somewhere else, it should implement ActionListener.
If it is just used internally as an ActionListener, implementing ActionListener would leak implementation details to the API of the class. Use composition in that case (has-a relationship).
This is true for other interfaces and superclasses as well.
This comes down to a style thing really. Both will perform exactly the same way in code.
The separate class will tend to keep the code inside your actual method simpler, whereas the anonymous inner class brings the code for the listener implementation within the method which can make it clearer what it is doing.
There is also the case that anonymous inner classes can access final variables in the method that creates them. You can't do that with a pre-written class (although you can pass the variables into the controller).
The separate code is re-usable - so if you have the same listener in multiple places then it is the clear winner.
If you use an anonymous class, the code becomes more readable, but you may not re-utilize it.
So, I would only use an anonymous class if it's short and I'm absolutely sure that I'll not have to use it again anywhere.
ActionListener is a interface but why can i create instance object?
JButton button = new JButton("Button1");
ActionListener me = new ActionListener(){
public void actionPerformed(ActionEvent ae){
JOptionPane.showMessageDialog(null,ae.getActionCommand());
}
};
button.addActionListener(me);
Or what else? I am not sure. Please help me.
What you're seeing here is called an anonymous class: me will be assigned an instance of an anonymous (un-named) class that implements the ActionListener interface.
Unlike say C#, Java's interfaces cannot prescribe a constructor.
What you are doing in your code is creating an anonymous class that extends java.lang.Object (which does have a default constructor) and implementing the interface.
What you have instantiated is an Anonymous Inner Class. In short, it's an in-line way to both define a class that has no name and instantiate an instance of that class in one statement. You'll only ever be able to refer to anonymous inner classes by the super class they implement or extend. In the case of this question, the super class is the ActionListener interface.
When you compile your code, there will be an extra .class file that exists with a name like this: OuterClass$1.class. That is the class file that represents the anonymous inner class you've defined.
If you want to learn more, check out this section in the JLS http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9.5
Because you're implementing the interface with your anonymous class
ActionListener itself is an interface, indeed.
However, the construct in your code is an anonymous inner class, meaning that your interface was implemented by that inner class.
Actually, what you are creating is an anonymous subclass of Object.class that implements the interface. So you are "inheriting" the Constructor from Object, not from the interface.
You are not creating an instance of ActionListener. You are creating an anonymous class which implements ActionListener and you are providing that implementation.
ActionListener is in fact an interface which can not be instantiated.
However, by defining public void actionPerformed() locally you are allowing the interface to act like a class.
This is legal:
ActionListener me = new ActionListener(){
public void actionPerformed(...){...};
};
This is not:
ActionListener me = new ActionListener();
1. You can't have constructor in Interface in java.
2. What you saw here is an Anonymous Class, which is declared and initialized simultaneously, and it must extend or implement a class or interface respectively.
In Swing I'm using ActionListener or any other Listener interface.
In general I can't create object of Interface.
If I use new operator with any constructor name a object is created.
I have a problem with my code below:
jbtOK : is some button object
ActionListener is an interface.
How can I use new ActionListener() in addActionListener method?
Since an object is created. but, I can't create a object from an interface.
Is it only possible in inner classes? i.e, in inner classes I can create objects of interface:
jbtOK.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("hi");
}
});
with the new keyword you create the object into the memory and as you create the object object of an interface it's need to be implement. lets compare with the explicit class
suppose you define the class which implement this ActionListener interface what you do?
class MyActionListener implements ActionListener{
// now here you need implement all of the method which defined into the ActionListener interface
}
now you can use this class to register listener for Action like this way
jbtOK.addActionListener(new MyActionListener());
this was the explicit implement and as you directly implement it's called Anonymous class as you defined here with ActionListener interface
If I understood your question, you cannot use the methods of an interface, because an interface has all its methods as abstract (empty, without implementation), then you have to implement all the methods requested by your interface.
For example, because you have to add an ActionListener to a button, then associate it to action called in actionPerformed method, you have to declare in the first lines of your code:
public class your_class implements ActionListener
Where the keyword implements is needed to indicate you are implementing the abstract methods of the ActionListener interface, or any other interface, to use these methods with your objects.
http://mindprod.com/jgloss/interface.html#INSTANTIATING:
You can’t instantiate an interface directly, but you can instantiate a class that implements an interface. References to an Object can by via the class name, via one of its superclass names, or one of its interface names.
Read also a few things about anonymous classes.
new class-name ( [ argument-list ] ) { class-body }
It is an anonymous class you are instantiating and passing to your addActionListener method. addActionListener takes an ActionListener as an argument, so since you provide an actionPerformed method it assumes that the anonymous class you pass to it is an ActionListener.
Try to change the name of this actionPerformed method. It will not work anymore since the anonymous class you are passing does not implement the ActionListener Interface. See the error message you get by the compiler.