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