Handle Events with Anonymous Inner Classes.
Author: vglass@jfind.com, Van Glass
When developing a Java GUI a good deal of work goes into setting up Event Listeners for
each component you wish to process events for. This usually involves having your class
implement one or more event listeners and overloading the necessary methods for those
subscribed components.
If you have a lot of components to deal with then managing these event listeners can often
be a big pain. For example, lets consider a Java applet which has several Buttons, each of
which performs a unique task when clicked upon. For each Button we must assign it an
ActionListener to process user clicks and overload the actionPerformed method.
By having our applet class implement ActionListener, and overloading the actionPerformed method, we
handle all subscribed Button events within our applet. Unfortunately, since every button is
subscribed to the same ActionListener our actionPerformed method must do some conditional
processing to determine which Button was clicked upon. This is typically done with a
nasty switch or if/else statement as shown below, and is not really a very good object oriented approach.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Testing extends Applet implements ActionListener
{
TextField txt1 = new TextField(10);
Button btn1 = new Button("Button1");
Button btn2 = new Button("Button2");
Button btn3 = new Button("Button3");
Button btn4 = new Button("Button4");
public void init()
{
add(txt1);
add(btn1);
add(btn2);
add(btn3);
add(btn4);
btn1.addActionListener(this);
btn2.addActionListener(this);
btn3.addActionListener(this);
btn4.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("Button1"))
{
txt1.setText("Button1 clicked");
}
else if(e.getActionCommand().equals("Button2"))
{
txt1.setText("Button2 clicked");
}
else if(e.getActionCommand().equals("Button3"))
{
txt1.setText("Button3 clicked");
}
else if(e.getActionCommand().equals("Button4"))
{
txt1.setText("Button4 clicked");
}
}
}
The other approach is to create a separate class for each component whose sole purpose
is to handle events subscribed to by that component. This is better in that it is more
object oriented however it creates a whole bunch of new class files that you have to keep
track of. Additionally by handling events in separate class you lose access to any member
variables of the applet. Not only that, but using this approach also increases the
amount of HTTP requests the browser must perform to load the applet.
So what do we do? What if we could encapsulate all of our event handling within our
applet class without sacrificing object oriented design? Well through the use of
anonymous inner classes we can do just that.
Anonymous classes are classes with no name and are instantiated with not just a
constructor, but the class definition itself. If you have never used anonymous classes before
then the syntax may look a bit awkward.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Testing extends Applet
{
TextField txt1 = new TextField(10);
Button btn1 = new Button("Button1");
Button btn2 = new Button("Button2");
Button btn3 = new Button("Button3");
Button btn4 = new Button("Button4");
public void init()
{
add(txt1);
add(btn1);
add(btn2);
add(btn3);
add(btn4);
/* Create anonymous inner class for each ActionListener */
btn1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
txt1.setText("Button1 clicked");
}
});
btn2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
txt1.setText("Button2 clicked");
}
});
btn3.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
txt1.setText("Button3 clicked");
}
});
btn4.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
txt1.setText("Button4 clicked");
}
});
}
}
Each component now has its own event listener, no evil if/else statements here. On top of that
all event handling is centralized within a single class making this class much easier to
manage. In the event a new component is added to this class then handling events for
this component simply requires the construction of a new anonymous event listener.
As a side note JBuilder is one of the few IDE's that by default uses anonymous inner classes
when defining event listeners. For instance when using the GUI designer if you double
click on a Button it will automatically generate the code for an anonymous inner class to act
as an event listener for that component.
| Sponsored Links - please visit our sponsors |
| Java FTP Component | | Easily add FTP to your Java apps. | | http://www.jscape.com/inetfactory/ftp.html |
| SSH Factory | | automate telnet and SSH tasks | | http://www.jscape.com/sshfactory/ |
| Java SMTP Component | | Easily add SMTP to your Java apps | | http://www.jscape.com/inetfactory/smtp.html |
| Secure FTP Applet | | Connect to FTP securely from within your browser. | | http://www.jscape.com/sftpapplet/ |
| Java POP3 Component | | Easily add POP3 to your Java apps | | http://www.jscape.com/inetfactory/smtp.html |
Sponsor this site
| |