Java 在扩展JPanel的类内未调用Button ActionListener

Java 在扩展JPanel的类内未调用Button ActionListener,java,macos,swing,user-interface,actionlistener,Java,Macos,Swing,User Interface,Actionlistener,我有一个称为FrontGUI的主框架,其中添加了一个侧面板。这个侧面板是一个名为FrontGUILinker的类,它扩展了JPanel,并在上面有一个按钮。当我运行程序时,按钮什么也不做——ActionListener似乎从来没有被调用过。我还有几个其他组件具有类似的设置,所有按钮都在它们上面工作-我能看到的唯一区别是它们是JFrame的扩展,它们不是FrontGUI的直接字段,而是下面代码中提到的maingui。此maingui包含具有每个帧的控制器类的字段,包括FrontGUIControl

我有一个称为FrontGUI的主框架,其中添加了一个侧面板。这个侧面板是一个名为FrontGUILinker的类,它扩展了JPanel,并在上面有一个按钮。当我运行程序时,按钮什么也不做——ActionListener似乎从来没有被调用过。我还有几个其他组件具有类似的设置,所有按钮都在它们上面工作-我能看到的唯一区别是它们是JFrame的扩展,它们不是FrontGUI的直接字段,而是下面代码中提到的maingui。此maingui包含具有每个帧的控制器类的字段,包括FrontGUIController,但FrontGuiInkerController是FrontGUIController中的一个字段。这里是我的课程大纲,希望只留下一些不相关的东西。主要JFrame类:

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);
    }
}
这是“控制器”类。侧面板可以显示,也可以不显示,这就是这个动作监听器所做的,它似乎工作得很好

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());
       }});

    }

}
下面是FrontGuillinker类:

public class FrontGUILinker extends JPanel {
   public btnCreateLink;

   public FrontGUILinker() {
       btnCreateLink = new JButton("Create Link");
       add(btnCreateLink);
   }
}
以下是该类的控制器:

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");
         }});
   }
}

有人知道为什么这不起作用吗?

您正在创建FrontGUILinker实例两次,一次显示,一次添加ActionListener。不要那样做。创建此对象一次,并对两者使用相同的引用。为了证明我是对的,只需查看上面问题中的代码,然后搜索您在哪里调用
new FrontGUILinker()
,您就会看到您这样做了两次,如下所示:

public FrontGUI() {
  linkerPanel = new FrontGUILinker();
在这里:

public FrontGUILinkerController(MAINGUI parent) {
  maingui = parent;
  frame = new FrontGUILinker();
每个实例都与另一个实例完全不同,因此向其中一个实例添加ActionListener不会对另一个实例(显示的实例)产生任何影响。要解决此问题,请将有效引用传递到需要它们的位置

i、 e


您是否在show/hide按钮操作侦听器中尝试了println,以查看是否实际调用了它?我经常在Swing中发现,更新请求在进行验证/重新验证/重新绘制组合之前并不总是“有效”。看,你的代码没有意义。你有两个班叫FrontGUILinker?我认为您为底层控制器类显示了错误的类名——一个令人讨厌的输入错误。请更正此问题。1)不要扩展
JFrame
,只需使用一个实例即可。2) (可能)也不要扩展
JPanel
(同上)。3) 为了更快地获得更好的帮助,请发布一个。4) 请学习类、方法和属性名称的通用(特别是用于名称的大小写)并一致使用。@HoverCraftFullOfels抱歉,现在已修复。最底层的控制器类是FrontGUILinkerController。@AndrewThompson 1和2)我们一直在扩展JFrame,以避免使类太大。似乎如果我们只使用JFrame和JPanel的实例,我们就必须将它们的各种按钮、文本框等的所有代码放在我们创建实例的一个类中。在不扩展JFrame和JPanel的情况下,有没有更好的方法来实现这一点?3) 我去看看!4) 这是一个我自己没有启动的现有项目,但我会记住这一点。我实现了这一点,但在FrontGUIController类中,我改为编写:
linkerController=new FrontGUILinkerController(maingui,frame.linkerPanel)
在FrontGUILinker控制器中,我必须删除整个
私有FrontGUILinker框架
行,并将
最终
添加到构造函数的框架参数中。我不完全确定为什么这些改变是必要的,所以任何解释都是受欢迎的,但它现在正在按预期工作!非常感谢。实际上,我可以保留
私有FrontGUILinker框架
行,以便在FrontGUILinker控制器的其他方法中使用它。它只是警告我没有使用它,因为我只使用了作为参数传递给FrontGuillinkerController()的帧。
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");
         }});
   }
}
public FrontGUIController(MAINGUI parent) {
   maingui = parent;
   frame = new FrontGUI();
   linkerController = new FrontGUILinkerController(maingui, frame); // **** changed