0

I've implemented an ActionListener as an inner class to my main class, and am attempting to call one of the main classes methods on an instance of that class. However it keeps returning a NullPointerException on the method call in the ActionListener.

Code provided.

Trying to click the "RefreshButton" appends the text to the TextArea, as expected, but then returns "Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at frontend.MainGUI$RefreshListener.actionPerformed(MainGUI.java:104)"

Which points to gui.testing(); in the RefreshListener. I'm probably missing something simple, but it's giving me a fair bit of trouble.

public class MainGUI {
    JFrame MainFrame;
    JLabel MainLabel;
    JLabel FooterLabel;
    JTextArea ListText;
    MainGUI gui;

public static void main (String[] args) {
   MainGUI staticGui = new MainGUI();
   staticGui.begin();
} // Close Main

public void begin() {
    gui = new MainGUI();
    gui.testing();
    gui.go();
}

public void go() {
    MainFrame = new JFrame();
    MainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // Setup Buttons, and their Listeners
    JButton RefreshButton = new JButton("Refresh");
    RefreshButton.addActionListener(new RefreshListener());

    // GUI stuff, working and unrelated, I think //      
    // Setup Labels
    MainLabel = new JLabel("Observations");
    Font Header = new Font("serif", Font.BOLD, 32);
    MainLabel.setFont(Header);

    FooterLabel = new JLabel("FooterText", SwingConstants.CENTER);
    Font Footer = new Font("serif", Font.PLAIN, 12);
    FooterLabel.setFont(Footer);
    FooterLabel.setForeground(Color.DARK_GRAY);

    // Setup Panel that holds the buttons
    MyDrawPanel buttonPanel = new MyDrawPanel();
    Dimension d = new Dimension(150,100);
    buttonPanel.setPreferredSize(d);
    buttonPanel.setBackground(Color.darkGray);
    //drawPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.Y_AXIS)); // Old Layout, Grid works better.
    buttonPanel.setLayout(new GridLayout(9, 1, 0, 1));

    // Setup Text area for displaying Observations        
    ListText = new JTextArea(24,48);
    ListText.setLineWrap(true);
    ListText.setMargin(new Insets(2,4,0,0)); // Text Padding, Top/Left

    JScrollPane scroller = new JScrollPane(ListText);
    scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
    scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        // Default Values
    ListText.setText("Nothing currently loaded...\n");
    ListText.append("Please import a HTML file.\n");
    ListText.setEditable(false);

    // Put Everything into JFrames
    MainFrame.getContentPane().add(BorderLayout.NORTH, MainLabel);
    MainFrame.getContentPane().add(BorderLayout.EAST, buttonPanel);
    MainFrame.getContentPane().add(BorderLayout.CENTER, scroller);
    MainFrame.getContentPane().add(BorderLayout.SOUTH, FooterLabel);
    buttonPanel.add(ImportButton);
    buttonPanel.add(RefreshButton);
    buttonPanel.add(ExitButton);

    //MainFrame Settings
    MainFrame.setSize(720, 480);
    MainFrame.setVisible(true);    
    MainFrame.setResizable(false);   

} // Close Go

public void testing() {
    System.out.print("TestMethodSuccess");
}

class ImportListener implements ActionListener { // Inner Class
    public void actionPerformed(ActionEvent event) {
    ListText.append("Import Button!\n");
    }
}

    class RefreshListener implements ActionListener { // Inner Class
     public void actionPerformed(ActionEvent event) {
      ListText.append("Refresh Button!\n");
      gui.testing();       // Error traces to here //
    }
}

    class CloseListener implements ActionListener { // Inner Class
    public void actionPerformed(ActionEvent event) {
    System.exit(0);
    }
} 

}  // Close Class

I've also tried the main method as the following, rather than using the begin() method, issue in the same place. This one's related to variable shadowing, I think? Anyway, a solution, or explanation for either would be great.

public static void main (String[] args) {
    MainGUI gui = new MainGUI();
    gui.go();
}
Data
  • 1
  • 1
  • For one, you're creating too many MainGUI objects. Create one and only one. – Hovercraft Full Of Eels Apr 19 '17 at 20:06
  • Change `gui.testing();` to `MainGUI.this.testing();` – Hovercraft Full Of Eels Apr 19 '17 at 20:10
  • For another, the MainGUI class should not have an instance field to itself. Instead refer to the `this` as noted above. – Hovercraft Full Of Eels Apr 19 '17 at 20:12
  • just one observation, I cannot find where did you initialize the ListText before invoking the append method on it, correct me if I'm wrong – Yahya Apr 19 '17 at 20:13
  • The SOLUTION IS: You created MainGUI gui; and you are calling it without referencing, all you need to do is change it to static , so it becomes static MainGUI gui; and it will work – Yahya Apr 19 '17 at 20:29
  • @John: no, please don't suggest that the OP throw out the baby with the bath water. No need to use statics when better, cleaner, OOP-compliant solutions are available. The solution is to not refer to null references. His code is way too convoluted and unnecessarily confused as it is, and the solution is to simplify and to make sure that references are used correctly. For example, please check out this [pastebin link](https://pastebin.com/t37Yv7Qd) – Hovercraft Full Of Eels Apr 19 '17 at 20:33
  • I agree with ya, but I tried it and it runs without errors when I changed it to static as expected – Yahya Apr 19 '17 at 20:35
  • @John: sure but that does not make your suggestion a good solution. He's making basic mistakes as I have noted, and it is far better for him to correct his mistakes than to throw in the towel and regress his program to pre-OOP programming. – Hovercraft Full Of Eels Apr 19 '17 at 20:39
  • Worked, and makes sense. Thank you. Apologies for the convoluted, and the mess. Learning. – Data Apr 20 '17 at 01:16

0 Answers0