-1

I have a problem with ActionListener. If I use an anonymous class everything works good, if the MainFrame class implements ActionListener everything works good. But if I create an extern class and implement ActionListener I get NullPointerException.

How can I fix this problem using an extern class that implement ActionListener interface?

Thanks in advance!

This is the code:

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class App {

    public static void main(String args[]) {

        SwingUtilities.invokeLater(new Runnable() {


            @Override
            public void run() {

                JFrame frame = new MainFrame("Hello world Swing");
                frame.setSize(500, 400);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
                frame.setVisible(true);
            }
        });
    }
}

MainFrame code:

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;

public class MainFrame extends JFrame {

    JTextArea textArea;

    public MainFrame(String title) {

        super(title);

        Container c = getContentPane();

        c.setLayout(new BorderLayout()); 

        textArea = new JTextArea();
        JButton button = new JButton("Click me!");

        c.add(textArea, BorderLayout.CENTER);
        c.add(button, BorderLayout.SOUTH);

        button.addActionListener(new ListenApp());  
    }
}

ListenApp code:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;

public class ListenApp implements ActionListener {

    MainFrame frame;

    @Override
    public void actionPerformed(ActionEvent e) {

            frame.textArea.append("Hello\n");   
    }
}
  • 1
    The `frame` is `null` because it is never assigned a value. Create a constructor `ListenApp(MainFrame f) { this.frame = f; }` and create the instance as `new ListenApp(this)`. (Actually, this is an answer, but I'd rather close this question as a duplicate of many, many, many `NullPointerException` questions. I wonder where the upvote came from...) – Marco13 May 11 '18 at 16:41
  • A somewhat more specific question (i.e. one that is more similar to yours) is https://stackoverflow.com/questions/18193308/nullpointerexception-for-instantiated-button-in-action-listener , but the canonical one is https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it – Marco13 May 11 '18 at 16:48

1 Answers1

0

It's because in ListenApp the frame (field) you have isn't declared as the frame you created in your main method.

They way to make it work is to pass the frame into the listener as an argument in the listener's constructor. Take a look:

MainFrame class:

package test;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class MainFrame extends JFrame {

    private JTextArea textArea; // private fields are always recommended.

    public MainFrame(String title) {
        super(title);
        Container c = getContentPane();
        c.setLayout(new BorderLayout());
        textArea = new JTextArea();
        JButton button = new JButton("Click me!");
        c.add(textArea, BorderLayout.CENTER);
        c.add(button, BorderLayout.SOUTH);
        button.addActionListener(new ListenApp(this)); //pass the frame to the listener
    }

    public JTextArea getTextArea() // Must have access to the textArea aswell
    {
        return textArea;
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new MainFrame("Hello world Swing");
                frame.setSize(500, 400);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

ListenApp class:

package test;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ListenApp implements ActionListener {
    private MainFrame frame;

    public ListenApp(MainFrame frame) {
        this.frame = frame;
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        frame.getTextArea().append("i append something");

    }

}
George Z.
  • 6,643
  • 4
  • 27
  • 47