Distinguish Timer (in Swing) event among the others

F

fix

Hi all,
I have some buttons and the timer, using the same action listener,
for the buttons, I can check by e.getSource() == buttonName,
but what about a Timer?
In the docs, Timer is the only thing that use the action listener,
so they don't do a check, and so I have no idea about it.
Thanks a lot!
fix.
 
C

Chris Smith

fix said:
Hi all,
I have some buttons and the timer, using the same action listener,
for the buttons, I can check by e.getSource() == buttonName,
but what about a Timer?
In the docs, Timer is the only thing that use the action listener,
so they don't do a check, and so I have no idea about it.
Thanks a lot!

I don't see any documentation guaranteeing the properties of an
ActionEvent generated by a Timer, so I wouldn't rely on anything in
particular. I suppose you could be safe in guessing that getSource() on
the ActionEvent would *not* return an instance of javax.swing.JButton,
though.

I guess I'm confused as to why you'd want to use the same ActionListener
for a Timer and a bunch of buttons. The Timer is almost certain to do
something completely unrelated, so why use the same ActionListener?

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
N

nos

Chris Smith said:
I don't see any documentation guaranteeing the properties of an
ActionEvent generated by a Timer, so I wouldn't rely on anything in
particular. I suppose you could be safe in guessing that getSource() on
the ActionEvent would *not* return an instance of javax.swing.JButton,
though.

I guess I'm confused as to why you'd want to use the same ActionListener
for a Timer and a bunch of buttons. The Timer is almost certain to do
something completely unrelated, so why use the same ActionListener?

i would like to guess on reason might be that the timer simulates user
pressing a button, like a default if user is not fast enough to click on a
real button
but you want to do the same thing as if user pressed the "default" button
 
F

fix

I don't see any documentation guaranteeing the properties of an
If it is a button, I could compare getSource() and the actual button,
i.e. e.getSource() == StartButton

I need ActionListener for handling button clicks and timer right?
Should I have them separated by writing an additional empty class
implementing the ActionListener.
i would like to guess on reason might be that the timer simulates user
pressing a button, like a default if user is not fast enough to click on a
real button
but you want to do the same thing as if user pressed the "default" button

Nice try...... but you don't have it. What I am actually doing is,
a pong game, the project of my computer science class,
we have some buttons for the user to click to start the game,
and keep refreshing to let the ball and paddles to go,
which I need to use Timer.
 
C

Chris Smith

fix said:
If it is a button, I could compare getSource() and the actual button,
i.e. e.getSource() == StartButton

Mmm? You would want to be comparing e.getSource() with a reference to
an object, not with the class name. Even if you've subclassed JButton,
you would need an instance to compare with. Alternatively, you could
compare based on the type. So either of the following would work for
the button:

if (e.getSource() == myStartButton) // myStartButton is an
// instance of StartButton

if (e.getSource() instanceof StartButton)

Whereas if it's the Timer (and the timer is the only event source that's
not a button), you don't know the actual expected source, but you could
do:

if (!(e.getSource() instanceof JButton))

Does that make any sense?
I need ActionListener for handling button clicks and timer right?

Yes, but why make them the *same* ActionListener? The API provides a
perfectly good method for registering listeners to specific components,
and then you want to throw all that out by adding the same listener to
everything, and then writing a kludgy series of if statements to figure
out what the event is?

There's simply no reason to do so. It probably doesn't even save any
keystrokes, since you replace the extra anonymous inner class
declarations with a big if-chain.

If you are trying to reuse code, then I can understand the motivation,
but I've found the better approach is to share methods declared in the
containing class, but have the entry points actually be different.
Should I have them separated by writing an additional empty class
implementing the ActionListener.

I don't know about an "empty" class... Your code goes in there, so it's
not empty.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
F

fix

Chris said:
Mmm? You would want to be comparing e.getSource() with a reference to
an object, not with the class name. Even if you've subclassed JButton,
you would need an instance to compare with. Alternatively, you could
compare based on the type. So either of the following would work for
the button:

if (e.getSource() == myStartButton) // myStartButton is an
// instance of StartButton

if (e.getSource() instanceof StartButton)

Whereas if it's the Timer (and the timer is the only event source that's
not a button), you don't know the actual expected source, but you could
do:

if (!(e.getSource() instanceof JButton))

Does that make any sense?

Yes, and I tried and it works. Actually if I am comparing by getSource()
== timerName, it worked too.
Yes, but why make them the *same* ActionListener? The API provides a
perfectly good method for registering listeners to specific components,
and then you want to throw all that out by adding the same listener to
everything, and then writing a kludgy series of if statements to figure
out what the event is?

There's simply no reason to do so. It probably doesn't even save any
keystrokes, since you replace the extra anonymous inner class
declarations with a big if-chain.

If you are trying to reuse code, then I can understand the motivation,
but I've found the better approach is to share methods declared in the
containing class, but have the entry points actually be different.

Yeah, you're right. So to implement this, should I put a class in the
containing class by just typing in "class someClass" and put all the
code and method in it?
I am a VB programmer, we have different "method"s for each components,
each type of events, for instance, Button1_Clicked, Button2_Clicked,
Text1_KeyDown, Text1_KeyUp, Timer1_Timer. But it does not really make
sense to me to have CLASSes to handle different events. I supposed that
they are used to be implementing some sort of real useful thing. Or
should I try hard to get used to it?
I don't know about an "empty" class... Your code goes in there, so it's
not empty.

Oh I meant excluding the event-handling method, it is "empty".
:)
 
C

Chris Smith

fix said:
Yes, and I tried and it works. Actually if I am comparing by getSource()
== timerName, it worked too.

Right, and that would make sense. On the other hand, I don't see an
explicit guarantee that this is the case, so I wouldn't rely on it.
Yeah, you're right. So to implement this, should I put a class in the
containing class by just typing in "class someClass" and put all the
code and method in it?

Sure, or it's less trouble to declare an anonymous class at the point
where you need it:

firstButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
// Your code here
}
});

secondButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
// Your code here
}
});

timer = new Timer(300, new ActionListener() {
public void actionPerformed(ActionEvent e)
{
// Your code here
}
});
I am a VB programmer, we have different "method"s for each components,
each type of events, for instance, Button1_Clicked, Button2_Clicked,
Text1_KeyDown, Text1_KeyUp, Timer1_Timer. But it does not really make
sense to me to have CLASSes to handle different events.

Okay. I don't have VB set up right now to check what I'm saying, and
it's been a couple years since I've worked with it, so please forgive me
if I don't remember correctly.

As I recall, VB does have classes, and they are used exclusively to
separate different pieces of code. As such, you expect to see a
completely different part of the application in a new class. The
corrolaries of this are that there's a reluctance to create new classes,
and that many parts of the language are designed to treat methods a
first-class elements.

In Java, it's not that way. A class is as big or as small as you need
it to be, and as such, there are "big" classes and then there are
classes that are easier to use and more local. Not that Java
applications are *not* broken up into classes; certainly they are... but
all classes don't represent major independent divisions of your code.
For example, the code I posted above is all a part of some big class,
but contains *three* complete smaller classes, which are so small that
they don't even get names. I don't have to go that far; I can also
declare a class that's named but may only be used within a single
method, or a class that's is only used within a single containing class,
or a class that's only used with a package, or a class that's visible to
the whole application. I pick whichever one meets my needs.

The point, then, is that you need an object that provides a certain kind
of behavior (that is, ActionListener), and you've got one. The specific
implementation class doesn't need a name, because all you need to know
about this object is that it provides this "ActionListener" sort of
behavior... the specific implementation is of very isolated importance.

Because you can do this kind of thing, and because defining a new class
is not nearly as much of a pain as it is in Visual Basic, it's generally
frowned upon to do some of the stuff that is done in Visual Basic to
*avoid* creating new classes. For example, your decision to reuse a
single object for listening to all kinds of events and then sorting them
out later is not a good one in Java.

Now, it may turn out that the behavior implemented by some
ActionListener instance becomes of such general importance that it's
worth sharing. In that case, it's trivial to move that local anonymous
class to a full top-level class with a name, and use it in other places
as well. However, you wouldn't do this unless the code that you've
written in the class really is widely applicable; otherwise, you're just
providing more top-level API than you need to provide, and making it
harder for others to approach your code.
Oh I meant excluding the event-handling method, it is "empty".
:)

Then yes... although since *the* purpose of that class is to implement
the response to that event, it still contains enough code to justify its
existence. There's nothing wrong with writing a class to contain one
method, especially when that class doesn't present a top-level API
element, and is only used to obtain the object behavior you need.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
F

fix

Chris said:
Right, and that would make sense. On the other hand, I don't see an
explicit guarantee that this is the case, so I wouldn't rely on it.

Oh I worked for me now and I do think it will work too for who's going
to grade my project. I'm not going to be a good Java programmer now but
a good student who submit his work on time. Hehe......
Sure, or it's less trouble to declare an anonymous class at the point
where you need it:

firstButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
// Your code here
}
});

secondButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
// Your code here
}
});

timer = new Timer(300, new ActionListener() {
public void actionPerformed(ActionEvent e)
{
// Your code here
}
});

Oh I looked a bit messy to me but it seems to be what I want, an event
handling procedure for each component.
Okay. I don't have VB set up right now to check what I'm saying, and
it's been a couple years since I've worked with it, so please forgive me
if I don't remember correctly.

As I recall, VB does have classes, and they are used exclusively to
separate different pieces of code. As such, you expect to see a
completely different part of the application in a new class. The
corrolaries of this are that there's a reluctance to create new classes,
and that many parts of the language are designed to treat methods a
first-class elements.

In Java, it's not that way. A class is as big or as small as you need
it to be, and as such, there are "big" classes and then there are
classes that are easier to use and more local. Not that Java
applications are *not* broken up into classes; certainly they are... but
all classes don't represent major independent divisions of your code.
For example, the code I posted above is all a part of some big class,
but contains *three* complete smaller classes, which are so small that
they don't even get names. I don't have to go that far; I can also
declare a class that's named but may only be used within a single
method, or a class that's is only used within a single containing class,
or a class that's only used with a package, or a class that's visible to
the whole application. I pick whichever one meets my needs.

The point, then, is that you need an object that provides a certain kind
of behavior (that is, ActionListener), and you've got one. The specific
implementation class doesn't need a name, because all you need to know
about this object is that it provides this "ActionListener" sort of
behavior... the specific implementation is of very isolated importance.

Because you can do this kind of thing, and because defining a new class
is not nearly as much of a pain as it is in Visual Basic, it's generally
frowned upon to do some of the stuff that is done in Visual Basic to
*avoid* creating new classes. For example, your decision to reuse a
single object for listening to all kinds of events and then sorting them
out later is not a good one in Java.

Now, it may turn out that the behavior implemented by some
ActionListener instance becomes of such general importance that it's
worth sharing. In that case, it's trivial to move that local anonymous
class to a full top-level class with a name, and use it in other places
as well. However, you wouldn't do this unless the code that you've
written in the class really is widely applicable; otherwise, you're just
providing more top-level API than you need to provide, and making it
harder for others to approach your code.

Aha...... I learned something new, I have never seen anonymous classes
in my book. I did saw it in some examples on the Sun site but I can't
understand. Here it goes.
Yes, I rarely write classes in VB unless I need to pack some code into a
..dll library. We could survive without any classes.
But one thing that I really don't like is, the way Java is going to make
us program in OOP. If I have a program to write, which displays 1 to
100, which I don't need OOP, but I still need to make a class and put a
main method in. I think the main method is independent of the class. And
sometimes in a bigger program, we have a class with its content and a
main method really doesn't belong to them.
That's my little opinion. Anyway thanks for your help.
fix.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top