aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes Questin on listeners Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Questin on listeners" Watch "Questin on listeners" New topic
Author

Questin on listeners

Shashank Gokhale
Ranch Hand

Joined: Jan 07, 2003
Posts: 92
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?
*************************************


May the force of the Java be in all of us !!!
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4664
    
    5

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.


luck, db
There are no new questions, but there may be new answers.
Shashank Gokhale
Ranch Hand

Joined: Jan 07, 2003
Posts: 92
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?
Ralph Cook
Ranch Hand

Joined: May 29, 2005
Posts: 479
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
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4664
    
    5

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.
Shashank Gokhale
Ranch Hand

Joined: Jan 07, 2003
Posts: 92
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?





Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18987
    
    8

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.
Shashank Gokhale
Ranch Hand

Joined: Jan 07, 2003
Posts: 92
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?
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4664
    
    5

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.
Shashank Gokhale
Ranch Hand

Joined: Jan 07, 2003
Posts: 92
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?
Jared Malcolm
Ranch Hand

Joined: May 02, 2011
Posts: 54

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?


SCJA 6 (Studying for SCJP 6)
Ralph Cook
Ranch Hand

Joined: May 29, 2005
Posts: 479
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
Jared Malcolm
Ranch Hand

Joined: May 02, 2011
Posts: 54

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.
Shashank Gokhale
Ranch Hand

Joined: Jan 07, 2003
Posts: 92
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
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Questin on listeners