Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Button ActionListener not called inside class extending JPanel

I have a main frame, called FrontGUI, with a side panel added to it. This side panel is a class called FrontGUILinker that extends JPanel, and has a button on it. When I run the program, the button doesn't do anything - the ActionListener doesn't ever seem to be called. I have several other components with similar setups, and the buttons all work on them - the only difference I can see is that they are extensions of JFrame, and they aren't direct fields of FrontGUI but instead of the maingui mentioned in the code below. This maingui contains fields with Controller classes for each frame, including FrontGUIController, but the FrontGUILinkerController is a field in FrontGUIController. Here are outlines of my classes, with hopefully just the unrelated things left out. The main JFrame class:

public class FrontGUI extends JFrame {
    public FrontGUILinker linkerPanel;
    public JButton btnShowhideLinker;

    public FrontGUI() {
      linkerPanel = new FrontGUILinker();
      contentPane.add(linkerPanel, BorderLayout.EAST);

      btnShowhideLinker = new JButton("Show/Hide Linker");
      contentPane.add(btnShowhideLinker);
    }
}

Here's it's "controller" class. The side panel can be shown or not shown, which is what this action listener does, and this seems to work just fine.

public class FrontGUIController {
    public MAINGUI maingui;
    private FrontGUI frame;
    public FrontGUILinkerController linkerController;

    public FrontGUIController(MAINGUI parent) {
       maingui = parent;
       frame = new FrontGUI();
       linkerController = new FrontGUILinkerController(maingui);

       //Button: Show/Hide linkerPanel
       frame.btnShowhideLinker.addActionListener( new ActionListener() {
       @Override
       public void actionPerformed(ActionEvent arg0) {
           frame.linkerPanel.setVisible(!frame.linkerPanel.isVisible());
       }});

    }

}

Here is the FrontGUILinker class:

public class FrontGUILinker extends JPanel {
   public btnCreateLink;

   public FrontGUILinker() {
       btnCreateLink = new JButton("Create Link");
       add(btnCreateLink);
   }
}

Here is the controller for that class:

public class FrontGUILinkerController {
   public MAINGUI maingui;
   private FrontGUILinker frame;

   public FrontGUILinkerController(MAINGUI parent) {
      maingui = parent;
      frame = new FrontGUILinker();

      // Add listener to Create Link button
      frame.btnCreateLink.addActionListener( new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent arg0) {
             System.out.println("Create Link button has been clicked");
         }});
   }
}

Anybody have an idea why this isn't working?

like image 509
FrancesKR Avatar asked Oct 06 '22 21:10

FrancesKR


1 Answers

You're creating FrontGUILinker instances twice, one you're displaying and one you're adding an ActionListener to. Don't do that. Create this object once and use the same reference for both. To show that I'm right, just look at the code in your question above, and search out where you call new FrontGUILinker() and you'll see that you do it twice, here:

public FrontGUI() {
  linkerPanel = new FrontGUILinker();

and again here:

public FrontGUILinkerController(MAINGUI parent) {
  maingui = parent;
  frame = new FrontGUILinker();

Each instance is completely distinct from the other, and so adding an ActionListener to one will have no effect on the other one (the displayed one). To solve this, pass valid references to where they're needed.

i.e.,

public class FrontGUILinkerController {
   public MAINGUI maingui;
   private FrontGUILinker frame;

   // **** note change
   public FrontGUILinkerController(MAINGUI parent, FrontGUILiner frame) {
      maingui = parent;
      this.frame = frame;  // **** added
      // frame = new FrontGUILinker(); // **** commented out

      // Add listener to Create Link button
      frame.btnCreateLink.addActionListener( new ActionListener() {
         @Override
         public void actionPerformed(ActionEvent arg0) {
             System.out.println("Create Link button has been clicked");
         }});
   }
}

and

public FrontGUIController(MAINGUI parent) {
   maingui = parent;
   frame = new FrontGUI();
   linkerController = new FrontGUILinkerController(maingui, frame); // **** changed
like image 124
Hovercraft Full Of Eels Avatar answered Oct 10 '22 02:10

Hovercraft Full Of Eels