Forums Register Login

Questin on listeners

+Pie Number of slices to send: Send
Every single book Ive read shows that keylisteners are added to a window or frame only in public static void main().
So I was wondering how do you add a keylistener to a class that does not have the main method, or is this even possible? What I want to do is to have a main method that displays a frame and adds a keylistener to it to tell the frame to close when the user clicks the x or when he presses escape.


I want to create a separate class that displays objects on screen and that has a keylistener so that the objects can respond to user presses. Im not even sure how I would get that class to draw things to the frame set up by the main method class.

The code I have so far for the class (without the main method) is as follows. But how do I add the listener class and will this class be able to draw on the frame displayed by the other class?
*************************************
+Pie Number of slices to send: Send
 

Shashank Gokhale wrote:Every single book Ive read shows that keylisteners are added to a window or frame only in public static void main().



You seem to have been exposed to some bad sample codes.

So I was wondering how do you add a keylistener to a class that does not have the main method, or is this even possible? What I want to do is to have a main method that displays a frame and adds a keylistener to it to tell the frame to close when the user clicks the x or when he presses escape.



The most common idiom is to add an event listener as an anonymous inner class. Example of adding an ActionListener to a JButton:

The code I have so far for the class (without the main method) is as follows. But how do I add the listener class and will this class be able to draw on the frame displayed by the other class?



Implementing a listener doesn't add that listener to the component that needs to listen for events. Read more here:
http://download.oracle.com/javase/tutorial/uiswing/events/index.html

And since this topic is GUI related, I'm moving this thread.
+Pie Number of slices to send: Send
Youre right, Ive probaby been looking at bad code

I know how to add an action listener to an object like a Jbutton, but if I want to define a JFrame, then how would I add a keylistener to that? In the code snippet you gave, there is reference to a button, the addActionListener, and the inner class for the action listener handler. But in the case of a JFrame, there is no such object that refers to the JFrame. There is only the class identifier line (public class gui extends JFrame). If I then say JFrame f=new JFrame(); then am I no creating a new Frame object that is different from the one that was inherited through the extends keyword? So , if I dont have a line that defines a new JFrame, then to what object would I add the listener?
+Pie Number of slices to send: Send
That would be the current object, referred to in Java as this.

If your current object extends JFrame, and you are in an instance method, you can enter



or even



if your current class also happens to implement the KeyListener interface.

Note that you cannot do this within a static method; in a static method, a reference to 'this' is illegal because you are not executing within the context of an object. So to make this work in a class that is also the class that contains main(), you need to instantiate the class and then execute some method on that object, and use 'this' within that method or something that it calls.

rc
+Pie Number of slices to send: Send
Adding a KeyListener to a top level window rarely makes sense. Read the API for JFrame and JRootPane to understand why.

I have a strong feeling that the solution to whatever problem you're facing lies in Key Bindings.

Also, it's rarely necessary to extend JFrame, and codes that do this are 99.999% cases of misuse of inheritance. A class can contain a JFrame, either as an instance field (for the few cases where it is desirable to have a reference to the frame that can be accessed from any method) or more usually, as a local variable in the one method that constructs the frame, sets its properties, adds content and makes the frame visible.
+Pie Number of slices to send: Send
rc,

I guess thats one thing Im confused on, if my current class implements the action listener and i instantiate the class, then I understand that
object.addkeylistener(this)
is
the same as
this.keylistener(this)

because im calling the implementing object, which is the current object to add a listener to the current object.

And in either case I would have to implement the abstract methods of the listeners class like keyPressed().

So in my code, if I remove the JFrame j=new JFrame() line, and put the addlistener line in the constructor for hoppinballImg, I still get compile error 'The method addKeyListener(hoppingballImg) is undefined for the type hoppingballImg'. Its probably cause I havent created an object of hoppingballImg yet. So the question is, can I somehow add the keyListener to the class that implements it, or do I have to make objects in the public static void main method and then add the listener there?





+Pie Number of slices to send: Send
I suspect you want

rather than


However note what Darryl said about JFrame and key listeners.

I also find it confusing that you've got a class (hoppingballImg) which appears to be some kind of graphical component, and yet it's also a KeyListener. It seems strange to lump two completely different responsibilites into a single class. That's probably (again) because you've been reading bad old code, in which big chunks of code would implement all kinds of listeners willy-nilly. As Darryl also said, it's better to write an anonymous inner class whose responsibility is just to be a KeyListener and nothing else.
+Pie Number of slices to send: Send
Yes I know that I can use an anonymous inner class to implement a listener, like in the following


Alternatively I can also define a separate class to implement the listener and then use the name of that class as the argument to the addkeylistener statement.


Yet another way is what I did earlier which is to extend the JFrame and implement the keylistener for the same class and then implement the listener methods, but I guess its a bad way to code, so Ill stick with the anonymous inner class.


I was following the example given at the http://download.oracle.com/javase/tutorial/uiswing/events/actionlistener.html link, which says you can extend a class and implement a listener at the same time.

But I think I understand a little better now, correct me on the following if Im wrong.
If I extend a JFrame or some other windowed component into my class, then I wont be able to add a listener to the component I inherited cause there is no object of that component. So if I write

then I wont be able to add a listener to the frame object cause there is none. Its only if I add an object like JButton that I can add a listener because when I say
JButton b=new JButton();
I am telling the compiler, hey here is an object now.

If I wanted to add a listener to a frame, then instead of extending the JFrame in my class, I should have typed


Is my understanding correct?
+Pie Number of slices to send: Send
 

Shashank Gokhale wrote:Yes I know that I can use an anonymous inner class to implement a listener, like in the following


That's right.

Alternatively I can also define a separate class to implement the listener and then use the name of that class as the argument to the addkeylistener statement.


No!


Yet another way is what I did earlier which is to extend the JFrame and implement the keylistener for the same class and then implement the listener methods, but I guess its a bad way to code, so Ill stick with the anonymous inner class.


Yes, that's usually a better approach.

If I extend a JFrame or some other windowed component into my class, then I wont be able to add a listener to the component I inherited cause there is no object of that component. So if I write

then I wont be able to add a listener to the frame object cause there is none.


Huh?You just showed a way. Your code, not mine:

If I wanted to add a listener to a frame, then instead of extending the JFrame in my class, I should have typed


Wouldn't compile, since a JFrame doesn't have that method, seeing as it never fires an ActionEvent. But conceptually, it's OK.
+Pie Number of slices to send: Send
Darryl,
So what youre saying is that



wont work? I mean I did leave out one thing, that I need to create an instance of the keylistener class kl, so if I write kl l=new kl(); or use new kl() as the argument to addkeyListener like you said, then would it work




Can I add the keylistener to the object only in a class constructor, or can I do it anywhere after I begin writing the class?

For my last code

I meant addKeyListener, my bad? But it will compile then right?
+Pie Number of slices to send: Send
Please correct me if I'm wrong (I probably am), but I thought excessive use of the anonymous inner classes could cause a performance hit. Granted I read this when referring to GWT, but would this apply when referring to an application?
+Pie Number of slices to send: Send
 

Jared Malcolm wrote:Please correct me if I'm wrong (I probably am), but I thought excessive use of the anonymous inner classes could cause a performance hit. Granted I read this when referring to GWT, but would this apply when referring to an application?


Excessive use of almost anything could cause a performance hit. Depending, of course, on what you mean by "excessive" and what your alternatives are.

I think there are two situations where the "performance hit" of any individual technology are worthy of consideration: extreme performance needs, and pathological implementations. Extreme performance needs are ones where the hardware is barely adequate to the task or the job is one that has special requirements; it takes days to calculate, or it is a real-time system where a certain speed of response is paramount. Pathological cases are ones where you choose an implementation that causes you to do something so many times that you have to consider the cost of each time.

Extreme performance needs might include modeling airflow across the surface(s) of a complicated bomber plane. You'll want to do that multiple times, you'll want it to complete in a reasonable time, you are going to be doing certain calculations an unthinkable number of times. So in those calculation areas, performance is a reasonable thing to consider.

I once saw a pathological case where someone was thinking about an editor design, and deciding to use an object for each character typed in the editor. It sure gives you maximum flexibility -- every letter can have its own set of characteristics -- and one might even make it work, after a fashion, with today's computers. But this was 1999, the computer in question was mobile running on batteries, and the editor didn't need THAT much flexibility. And a good thing, since a mobile in 1999 didn't have the necessary CPU or memory for that implementation.

Creating inner classes may have a performance degradation in comparison to "outer classes", but it doesn't seem to me anyone has talked about any extreme situation in this case, and therefore I don't think the performance hit is worth considering.

rc
+Pie Number of slices to send: Send
Gotcha, I generally go the inner class route for most of my coding and like I said this concern was brought up in a book/website (don't remember) that was dealing with GWT/web apps and I was quite curious about the relevance to a desktop app.
+Pie Number of slices to send: Send
I want to create a program that consists of several classes.

Class hoppingballImg creates each ball object, and gives it some initial position values x and y. I want to add a keyListener to each ball object so that depending on what the user presses the ball moves right left up or down.

Class hoppingballmain creates a specific number of balls by calling hoppingballImg that many times, say 2 times. I also want to display a fullscreen JFrame, and implement the keylistener on it so that the user presses escape to close the window and end the program. I dont know how to add a keylistener in this class because

Class hoppingball handles the motion of each of the balls according to what the user presses, and draws the balls on the frame created by hoppingballmain.

Can anyone show me how to do this
There is no "i" in denial. Tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com


reply
reply
This thread has been viewed 2008 times.
Similar Threads
KeyListener Stops Working
Adding a KeyListener to a JLabel?
using JFrame with KeyListener Interface and using paint method
how to paint a particular word in a string ?
Please help with this program
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 28, 2024 09:05:56.