Reputation: 381
While making a small game in Java, I stumbled upon the keyListener class, which asks for three methods when instanced (keyTyped, keyPressed, and keyReleased), as below:
JFrame.addKeyListener(new KeyListener(){
public void keyTyped(KeyEvent evnt) {
//blah
}
public void keyPressed(KeyEvent evnt) {
//blah
}
public void keyReleased(KeyEvent evnt) {
//blah
}
});
How can I get a class I am making on my own accept methods as a parameter as above?
Upvotes: 1
Views: 386
Reputation: 381
I know that it is weird to answer my own question, but...
I figured it out. You have to make your class abstract, and you can declare abstract methods to make methods "parameters" to have it behave like a KeyListener declaration. Abstract methods are declared like this:
abstract ReturnType name(Parameter p);
and behave exactly like methods when called. For a full example:
//The abstract keyword enables abstract methods to work with this class.
abstract class Foo {
//Just a random variable and a constructor to initialize it
int blah;
public Foo(int blah) {
this.blah = blah;
}
//An abstract method
abstract void doStuff();
//Example with a parameter
abstract void whatDoIDoWith(int thisNumber);
//A normal method that will call these methods.
public void doThings() {
//Call our abstract method.
doStuff();
//Call whatDoIDoWith() and give it the parameter 5, because, well... 5!
whatDoIDoWith(5);
}
}
When you try to instance an abstract class like a normal class, Java will freak out.
Foo f = new Foo(4);
What you will have to do is something like this:
Foo f = new Foo(4) {
@Override
void doStuff() {
System.out.println("Hi guys! I am an abstract method!");
}
@Override
void whatDoIDoWith(int thisNumber) {
blah += thisNumber;
System.out.println(blah);
}
}; //Always remember this semicolon!
Note that you need to include all of the abstract methods here, not just some of them. Now, let's try this:
public class Main {
public static void main(String[] args) {
//Instance foo.
Foo f = new Foo(4) {
@Override
void doStuff() {
System.out.println("Hi guys! I am an abstract method!");
}
@Override
void whatDoIDoWith(int thisNumber) {
blah += thisNumber;
System.out.println(blah);
}
};
//Call our method where we called our two abstract methods.
foo.doThings();
}
}
This prints the following to the console:
Hi guys! I am an abstract method!
9
Upvotes: 0
Reputation: 88707
new KeyListener() { ... }
actually creates an anonymous inner class that implements KeyListener
. As such it can access any visible field of the class that created it as well as any local final variable inside the method that called the constructor.
Example:
class Outer {
int x;
void initUI( final int z) {
final int y = 0;
int nope = 1; //you can't access this since it is neither final nor a field like x
JFrame.addKeyListener( new KeyListener() {
public void keyTyped(KeyEvent evnt) {
System.out.println( x + y + z ); //you can access all of them
}
});
}
}
If you want to provide a constructor for your key listener you'll need to explicitly define a class, as anonymous classes can't have custom constructors. That means you'd have to do something like this (attention: pseudo code):
class Outer {
void initUI() {
JFrame.addKeyListener( new InnerKeyListener( myParam ) );
}
class InnerKeyListener implements KeyListener {
InnerKeyListener( Param p ) {
}
...
}
}
Of course you can put the inner class into a separe file as well or make it a static inner class.
Upvotes: 1
Reputation: 13589
Technically, those methods aren't parameters here. The only parameter is the one anonymous instance of a KeyListener.
KeyListener is an interface
that requires those 3 methods to be implemented.
If you want to define your own interface, it looks similar to a class:
public interface SomeInterface {
public void foo();
public int bar(int x);
}
Then you can use it anonymously (like in your example), or by implementing it in a class:
public class MyClass implements SomeInterface {
// ...
}
Upvotes: 1
Reputation: 97
It's not accepting methods as a parameter. You're declaring an anonymous class and passing that as a parameter into the addKeyListener method.
Upvotes: 0