aspose file tools*
The moose likes Beginning Java and the fly likes separate Event Listener class Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "separate Event Listener class " Watch "separate Event Listener class " New topic
Author

separate Event Listener class

Lisa Bergeron
Greenhorn

Joined: Nov 27, 2003
Posts: 7
I need to take the following code and instead of having the ActionListener implemented by the JFrame class, I have to create a separate class. I think I know how to call the separate ActionListener class from the JFrame class, however, creating the separate ActionListener class is posing a challenge. Anyone??
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JFrame5 extends JFrame implements ActionListener {
Container c = this.getContentPane();
Toolkit kit = Toolkit.getDefaultToolkit();
ImageIcon img1 = new ImageIcon("c:\\Javagrl\\One.jpg");
ImageIcon img2 = new ImageIcon("c:\\Javagrl\\Two.JPG");
ImageIcon img3 = new ImageIcon("c:\\Javagrl\\Three.JPG");
JPanel top = new JPanel();
JPanel bottom = new JPanel();
JPanel center = new JPanel();
JPanel jp1 = new JPanel();
JPanel jp2 = new JPanel();
JPanel jp3 = new JPanel();
JLabel lab1 = new JLabel(img1);
JLabel lab2 = new JLabel(img2);
JLabel lab3 = new JLabel(img3);
JButton ImageOne = new JButton("Image One");
JButton ImageTwo = new JButton("Image Two");
JButton ImageThree = new JButton("Image Three");
CardLayout card = new CardLayout();
FlowLayout flow = new FlowLayout();
// remember that a frame has a default layout of border
public JFrame5() {
super();
}
public JFrame5(String title) {
super(title);
}
public void createJFrame() {
this.setDefaultCloseOperation(3);
this.setSize(500, 500);
this.show();
}
public void makePanels() {
bottom.setLayout(flow);
flow.setHgap(10);
top.add(ImageOne);
top.add(ImageTwo);
top.add(ImageThree);
ImageOne.addActionListener(this);
ImageTwo.addActionListener(this);
ImageThree.addActionListener(this);
center.setLayout(card);
jp1.add(lab1);
jp2.add(lab2);
jp3.add(lab3);
center.add(jp1, "firstPanel");
center.add(jp2, "secondPanel");
center.add(jp3, "thirdPanel");
card.show(center, "firstPanel");
c.add("South", bottom);
c.add("Center", center);
c.add("North", top);
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == ImageOne) {
card.first(center);
}
if (source == ImageTwo) {
card.next(center);
}
if (source == ImageThree) {
card.last(center);
}
}
}
chi Lin
Ranch Hand

Joined: Aug 24, 2001
Posts: 348
define one more class like,
class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent e){
...
...
}
}
in the JFrame5, one line like
addActionListener(new MyActionListener() );
[ December 01, 2003: Message edited by: chi Lin ]

not so smart guy still curious to learn new stuff every now and then
Lisa Bergeron
Greenhorn

Joined: Nov 27, 2003
Posts: 7
Thanks,
I do know HOW to construct a basic class. I guess what I can't figure out is how to call the event listener from theJFrame class. ALso, the event listener will need to DO something (Action event). If this method is in the separate Event Listener class...that class does not know what a card is, what an image is, etc....not sure if I am making myself clear, I am very fuzzy on this.
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == ImageOne) {
card.first(center);
}
if (source == ImageTwo) {
card.next(center);
}
if (source == ImageThree) {
card.last(center);
}
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
It's common to make listeners as anonymous inner classes. Then they have access to the outer class's variables and methods. (If inner & outer classes are not familiar, ask about that next!) Here's an example I could put my hands on quickly, taken from the initialization code in a JFrame:

addWindowListner is a standard JFrame thing. By saying "new someInterfaceName()" we indicate we want to define a class that implements an interface and create an instance all at once. Then in the next set of braces we define the class with just the one method. The inner class as access to the outer class methods, so it can call exitForm on the frame. Neat, huh?
I like to avoid putting any logic in these listeners, but just have them forward the event to another method. Then you could call the same method from a menu listener, a button listener, a window listener, etc.
Hope that gets you going!


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Lisa Bergeron
Greenhorn

Joined: Nov 27, 2003
Posts: 7
Thanks.
I have been tasked with making this code work three ways.
A separate outer Listener Class, as an inner class, and also to make the componeent (in this case the JFrame) a listener itself.
I have completed the inner class and using the JFrame as a listener. (ie: MyJFrame extends JFrame implements ActionListener). I am still stuck on creating this separate Listener class...the below code won't work because my action listener does not know what a card is or what an ImageIcon is, etc....I just know this has to be simple but I have a serious block!
public class MyListener extends ActionListener{
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == ImageOne) {
card.first(center);
}
if (source == ImageTwo) {
card.next(center);
}
if (source == ImageThree) {
card.last(center);
}
}
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Ah, you've already been where I went. Sorry about that. You are right, your external listener won't have access to the methods and variables in the JFrame without some work. One option: When you create the external listener, give it a reference to the frame:

This is probably not precisely right, but you get the idea that the listener has to go through the parent frame to get references to anything it wants to work on.
This has a lot of coupling. That is, the listener knows too much about the frame. And it violates the Don't Confuse Your Dog rule.
We could decouple these a bit by leaving all the logic on the frame and just letting the frame know something has happened. Maybe the actionEvent would look like:

The method theUserClicked(source) looks an awful lot like the original actionEvent in your example, but you've satisfied the assignment without too much new coupling. Hope that helps!
[ December 05, 2003: Message edited by: Stan James ]
Lisa Bergeron
Greenhorn

Joined: Nov 27, 2003
Posts: 7
Thank you so much - that was awesome and even entertaining - the way Java should be! I understood right away. This is what ended up in my Listener Class: I could only get it to work by also creating an instance of the JFrame here. If I take that away, it won't work.
public class MyActionListener implements ActionListener {
public MyActionListener(JFrame6 parent) {
myParent = parent;
}
JFrame6 myParent = new JFrame6();
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == myParent.ImageOne) {
myParent.card.first(myParent.center);
}
if (source == myParent.ImageTwo) {
myParent.card.next(myParent.center);
}
if (source == myParent.ImageThree) {
myParent.card.last(myParent.center);
}
}
}
I also did this in my JFrame Class:
ImageOne.addActionListener(new MyActionListener(this));
ImageTwo.addActionListener(new MyActionListener(this));
ImageThree.addActionListener(new MyActionListener(this));
It worked first try! Thanks again - class is tomorrow - maybe I can have a life tonight
 
wood burning stoves
 
subject: separate Event Listener class