在 ActionListener 中添加 GridBagLayout 时遇到问题
Posted
技术标签:
【中文标题】在 ActionListener 中添加 GridBagLayout 时遇到问题【英文标题】:Trouble adding a GridBagLayout inside an ActionListener 【发布时间】:2012-10-11 20:23:51 【问题描述】:我有一个JMenuItem
和一个ActionListener
,在这个ActionListener
我想在我的frame
中添加一个GridBagLayout
(它可能有也可能没有添加一个内容窗格 - 用于测试目的没有),然后将components
添加到frame
。 frame works
的设计是自己的,但我想从 ActionListener
到 JMenuItem
上的 trigger
它,这就是我遇到问题的地方。它不会从ActionListener
内部显示。我已经尝试从 AL 类中的不同方法运行相同的代码,但也没有用。
当我完全注释掉ActionListener
时,我要测试的JLabel
在正确的位置添加到GBL
,系统prints
我的debug
行这里 和这里2。 compiler
没有发现语法错误。这会产生所需的结果,并打印标签。 (请参阅下面的图片,了解当我完全注释掉 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 - 将动作添加到 JButtons 的 ArrayList
如何在 Java 中将 ActionListener 添加到 JButton 上