【问题标题】:Why does a JButton not show unless text is set after JButton is added to JPanel?为什么在将 JButton 添加到 JPanel 后除非设置文本,否则 JButton 不显示?
【发布时间】:2014-12-04 02:25:04
【问题描述】:

我的 JButton 对象行为异常有问题:

JFrame frame = new JFrame();
frame.setSize(new Dimension(200, 200));
frame.setVisible(true);

//Constraints
GridBagConstraints constraints = new GridBagConstraints();
constraints.weightx = 1.0;
constraints.weighty = 1.0;
...
//

JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
JButton button = new JButton("Categories:");
panel.add(button, constraints);
frame.add(panel);

这会产生以下 GUI:

按钮在哪里?

当我将最后几行替换为以下内容时:

JPanel panel = new JPanel();
JButton button = new JButton();
panel.add(button, constraints);
button.setText("Categories:");

frame.add(panel);

我得到以下图形用户界面:

按钮现在出现了。

这是为什么?我认为在按钮的构造函数中给出一个字符串会导致与显式调用 setter 相同。

【问题讨论】:

  • frame.setVisible(true); 成为你调用的最后一件事,打赌它会起作用......
  • 谢谢疯狂程序员。我应该将自己命名为 NoobProgrammer。干杯!

标签: java swing jframe jpanel jbutton


【解决方案1】:

正如人们指出的那样,应该在你 pack() 框架并使框架可见之前将组件添加到 GUI。

为什么在将 JButton 添加到 JPanel 之后,除非设置文本,否则 JButton 不显示?

但是,要回答上述问题,即使框架可见,您也可以将组件添加到 GUI。当您这样做时,您必须告诉 Swing 组件已被添加(或删除),以便可以调用布局管理器。您可以使用如下代码执行此操作:

panel.add(...);
panel.revalidate();
panel.repaint();

在您的情况下,当您在按钮上调用 setText(...) 方法时,按钮实际上会为您调用 revalidate() 和 repaint()。每当您更改 Swing 组件的属性时,都会执行此操作,从而有效地调用布局管理器,这意味着布局管理器可以在绘制按钮之前为其分配大小/位置。

在您的原始代码中,当您将按钮添加到 GUI 时未调用布局管理器,因此它的默认大小为 (0, 0);

【讨论】:

    【解决方案2】:

    正如 MadProgrammer 指出的(谢谢!),问题是由 frame.setVisible(true) 的位置引起的。

    这必须是最后一个调用,否则框架的刷新模式可能会导致未渲染的组件,就像我的情况一样。

    【讨论】:

      猜你喜欢
      • 2011-05-06
      • 2013-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-18
      • 2023-03-05
      相关资源
      最近更新 更多