Obvious_Grapefruit
Obvious_Grapefruit

Reputation: 890

Avoid infinite loop when Java Swing Action Listener class extends another class

I've attached an ActionListener to a JButton in Swing.

The main class:

 class MainClass {

    String foo;
    JButton button = new JButton("cool button");

    public MainClass(String foo) {
        this.foo = foo;
        ...
        JFrame setup here
        ...

        button.addActionListener(new MyBtnListener(frame));
        System.out.println(getFoo());
    }

    public String getFoo() {
        return this.foo;
    }

}

The class that implements the ActionListener methods:

class MyBtnListener extends MainClass implements ActionListener  {

    private JFrame target;

    public MyBtnListener(JFrame target) {
        this.target = target;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("button clicked");
        //target.dispose();
    }

}

When compiled, the code results in something like this: foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo (an infinite loop). I need the ActionListener class to be able to access methods in MainClass, while at the same time not repeatedly calling the constructor. How can I achieve this?

Upvotes: 0

Views: 268

Answers (2)

user7338524
user7338524

Reputation:

The answer to your question is pretty straight forward: what you search for is called a „reference“.

Just add a private field of the type MainClass to your listener and initialise it in the constructor:

private final JFrame frame;
private final MainClass reference;

public MyBtnListener(final JFrame frame, final MainClass reference)
{
     this.frame = frame;
     this.reference = reference;
}

Then you can just invoke the getFoo method like this:

final String foo = reference.getFoo();

It is also very important that the MyBtnListener class doesn't extend the MainClass class.

Upvotes: 1

M. le Rutte
M. le Rutte

Reputation: 3563

By having MyBtnListener extend MainClass and MainClass having creating a MyBtnListener in its constructor you have created a loop that lasts as long as there is space on the call stack.

Move the button.addActionListener(new MyBtnListener(frame)); to the constructor of MyBtnListener as button.addActionListener(this); or don't have MyBtnListener extend MainClass, just have it implement ActionListener.

class MainClass {
 String foo;
 JButton button = new JButton("cool button");

 public MainClass(String foo) {
    this.foo = foo;
    ...
    JFrame setup here
    ...

    button.addActionListener(new MyBtnListener());
    System.out.println(getFoo());
}

public String getFoo() {
    return this.foo;
}
}

class MyBtnListener implements ActionListener  {
@Override
public void actionPerformed(ActionEvent e) {
    System.out.println("button clicked");
}

}

Upvotes: 0

Related Questions