在 ActionListener 中添加 GridBagLayout 时遇到问题

Posted

技术标签:

【中文标题】在 ActionListener 中添加 GridBagLayout 时遇到问题【英文标题】:Trouble adding a GridBagLayout inside an ActionListener 【发布时间】:2012-10-11 20:23:51 【问题描述】:

我有一个JMenuItem 和一个ActionListener,在这个ActionListener 我想在我的frame 中添加一个GridBagLayout(它可能有也可能没有添加一个内容窗格 - 用于测试目的没有),然后将components 添加到frameframe works 的设计是自己的,但我想从 ActionListenerJMenuItem 上的 trigger 它,这就是我遇到问题的地方。它不会从ActionListener 内部显示。我已经尝试从 AL 类中的不同方法运行相同的代码,但也没有用。

当我完全注释掉ActionListener 时,我要测试的JLabel 在正确的位置添加到GBL,系统prints 我的debug这里这里2compiler 没有发现语法错误。这会产生所需的结果,并打印标签。 (请参阅下面的图片,了解当我完全注释掉 AL 时会发生什么。)有问题的代码的 sn-p(在哪个框架中是我的 JFrame)如下:

// (frame created, menus added, etc.) ...
JMenuItem vPoke1Item = new JMenuItem("Pokemon 1");
vPoke1Item.setActionCommand("poke1");
viewMenu.add(vPoke1Item);

//Setup GBL to view stats for Pokemon 1
  vPoke1Item.addActionListener(new ActionListener() 
      public void actionPerformed(ActionEvent e)
      
//        debug output
          System.out.println("here");

//        Set up the content pane
          frame.getContentPane().removeAll();
          GridBagLayout gbl = new GridBagLayout();
          GridBagConstraints gbc = new GridBagConstraints();
          Container pane = frame.getContentPane();
          pane.setLayout(gbl);

//        Make a StatCalcObject (all my labels/fields are already initialized)
          StatCalc1 sc1 = new StatCalc1();

//        Add it to pane
          gbc.gridx = 0;gbc.gridy = 0;gbl.setConstraints(sc1.speciesL, gbc);
          pane.add(sc1.speciesL);
          frame.revalidate();
          frame.repaint();

//        debug output
          System.out.println("here2");
      
  );
// (etc.)

现在,当我运行此代码时,我仍然可以打印调试行“here”和“here2”,因此它告诉我 ActionListener 运行良好。但是标签没有出现。编译器仍然没有发现语法错误。所以我在这里挠头。我究竟做错了什么?我希望这段代码 sn-p 足以理解问题,但如果您想要完整的代码,我可以提供。

【问题讨论】:

既然您从根本上改变了 JFrame,我想知道您是否需要在上面重复调用 pack()。如果这没有帮助,并且您没有很快在这里得到体面的帮助,您可能希望创建并发布一个sscce(请阅读链接),以便我们可以运行、修改并尝试帮助您解决您的问题和代码。 哇。对 pack() 的额外调用起作用了!无论如何,我已经在 AL 之后调用了它。但现在它可以工作了,它更新了窗格!谢谢一百万! 不客气,很高兴它有帮助。 madbean.com/anim/totallygridbag 您是否有理由更改现有框架而不是创建新框架?或者,您应该考虑将大部分 AL 代码重构为扩展 JPanel 的类。然后,您可以简单地创建 JPanel 的新实例以添加到 JFrame。 【参考方案1】:

如果您使用的是固定大小的窗口,如果您更换,一切都会正常

frame.revalidate();
frame.repaint();

pane.invalidate();
pane.validate();

pack();

如果您没有固定大小的框架。 请注意,JFrame 或 Container 不支持重新验证。 更换也比较好

gbl.setConstraints(sc1.speciesL, gbc);
pane.add(sc1.speciesL);

pane.add(sc1, gbc);

为了更好的代码风格。

【讨论】:

【参考方案2】:

查看调用方法pane.add(sc1.speciesL);时发生了什么

Container.add(sc1.speciesL, null, -1) 接下来调用

然后是Container.addImpl(Component comp, Object constraints, int index)

然后是 gbl.setConstraints(sc1.speciesL, gbc);被 null 取代。

  if (layoutMgr instanceof LayoutManager2) 
    ((LayoutManager2)layoutMgr).addLayoutComponent(comp, constraints);
  

然后面板没有显示您新添加的组件,因为 GridBagConstraints 现在为空

而且你实际上不需要强制

  frame.revalidate();
  frame.repaint();
  frame.pack();

您只需使用适当的方法将新组件正确添加到容器中:

pane.add(sc1.speciesL, gbc);

并删除无用的

gbl.setConstraints(sc1.speciesL, gbc);

【讨论】:

以上是关于在 ActionListener 中添加 GridBagLayout 时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

ActionListener添加到JButton但不起作用

ActionListener - 将动作添加到 JButtons 的 ArrayList

为打字游戏添加 ActionListener

如何在 Java 中将 ActionListener 添加到 JButton 上

如何在使用ActionListener按钮和GUI时向数组列表中添加项目?

组合 Swing 组件:如何添加添加 ActionListener 的功能?