Sign in to follow this  
natebuckley

[java] ActionListener - This the Correct Way?

Recommended Posts

Hello I'm just wondering if this is the correct way to deal with events? (CODE BELOW). I know this works fine as I've tested it I'm just making sure that I'm not over looking anything by doing it like this (apart from a hefty if/else if/else statement if the panel contains many controls.) Is there a better way way to deal with it? How would you do it? Thanks in advance! CODE
public class LoginPanel extends JPanel implements ActionListener{
...
	public LoginPanel(){
                ....
		btnLogin.addActionListener(this);
		btnQuit.addActionListener(this);
                ....
	}

	public void actionPerformed(ActionEvent e){
		if(e.getActionCommand() == "Login"){
			System.out.println("You pushed login");
		}
		else{
			System.out.println("You pushed Quit");
		}
	}
...
}

Share this post


Link to post
Share on other sites
Well, whether one way is correct and another incorrect ... I will not judge since it is often dependent on the situation. In the following there are some ways shown, 1 of them is your solution.

A single self-implemented listener working on all sources, dispatching by using the actionCommand; just the same as in the OP:

public class Anything
extends Object
implements ActionListener {

public Anything() {
...
button.setActionCommand("action");
button.addActionListener(this);
...
)

public void actionPerformed(ActionEvent event) {
if(event.getActionCommand()=="action") {
...
}
else if ...
}

}

Using the actionCommand is of advantage e.g. if you don't refer to the event sources, and/or there are several sources that can fire "action".

Instead of distpatching by command, you can use something like a mediator:

public class Anything
extends Object
implements ActionListener {

public Anything() {
...
this.button.addActionListener(this);
...
)

private Button button;

public void actionPerformed(ActionEvent event) {
if(event.getSource()==this.button) {
...
}
else if ...
}

}

Often you have the need to refer to event sources for other purposes anyway, e.g. to enable/disable then conditionally.

Next, with both of the ways above, you can hide self being an ActionListener by using an embedded listener (only shown for the 2nd variant here):

public class Anything
extends Object {

public Anything() {
...
this.button.addActionLIstener(this.actionListener);
...
)

private Button button;

private final ActionListener actionListener = new ActionListener() {

public void actionPerformed(ActionEvent event) {
if(event.getSource()==Anything.this.button) {
...
}
else if ...
}

}

}

You can instanciate the listener in Anything's initializer or so, too, if you want a more dynamic behaviour, of course. BTW: The above is the way I prefer.

With the embedded listener pattern, you can also drop the dispatching totally, if you use several listeners:

public class Anything
extends Object {

public Anything() {
...
this.button1.addActionListener(this.actionListener1);
this.button2.addActionListener(this.actionListener2);
...
)

private Button button1;

private Button button2;

private final ActionListener actionListener1 = new ActionListener() {

public void actionPerformed(ActionEvent event) {
...
}

}

private final ActionListener actionListener2 = new ActionListener() {

public void actionPerformed(ActionEvent event) {
...
}

}

}


In general, using an embedded listener allows you to hide the ActionListener interface from clients of the outer class, what normally is a Good Thing.

Share this post


Link to post
Share on other sites
You sir, are a star. I owe you a frosty cold beer.

That's made a lot more sense, I like the "embedded listener pattern" that you described and showed. I think I will make use of this in control mad panels.

Thanks again.

Share this post


Link to post
Share on other sites
An additional style like the embedded listener can also be used if your listener never needs to be removed/added or accessed by the containing class like the following, which is what I normally use since listeners I write rarely ever need changing or addition/removal from a component.

You can also access variables either local or class member variables within the ActionListener although the access is noted to be slower than if the listener had more direct access to it.

...
public class MyFrame extends JFrame {

private String strHello = "Hello World";

private JButton butHello = new JButton("Hello World!");

public MyFrame() {
super(strHello);

this.add(butHello);

butHello.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println(strHello);
//MyFrame.this is anonymous classes little secret sssshh
JOptionPane.showMessageDialog(MyFrame.this, strHello);
}
});

...
}
...
}



Good luck natebuckley!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this