使用BorderLayout时JPanel无法在JFrame中显示的问题排查
BorderLayout布局下JPanel无法显示的排查与解决
问题描述
尝试向JFrame中添加4个各包含若干组件的JPanel,这些面板在FlowLayout布局下可正常显示,但使用BorderLayout布局时却无法显示。目前已注释North和South面板,仅尝试让West和Center面板显示,但仍未成功。
原代码
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; import javax.swing.border.TitledBorder; public class Lab3 extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; public JPanel Westpanel, Centerpanel, Northpanel, Southpanel; public ButtonGroup size, ingredients; public JRadioButton small, medium, large; public JCheckBox let, kal, tom, on, bac, egg, che, can; public JButton BS, reset; public TitledBorder sizeborder, ingborder; public TextField bottom; public static void main(String args[]) { new Lab3(); } public Lab3() { Westpanel = new JPanel(); Centerpanel = new JPanel(); Northpanel = new JPanel(); Southpanel = new JPanel(); size = new ButtonGroup(); ingredients = new ButtonGroup(); small = new JRadioButton("Small"); medium = new JRadioButton("Medium"); large = new JRadioButton("Large"); let = new JCheckBox("Lettuce"); kal = new JCheckBox("Kale"); tom = new JCheckBox("Tomato"); on = new JCheckBox("Onion"); bac = new JCheckBox("Bacon"); egg = new JCheckBox("Egg"); che = new JCheckBox("Cheese"); can = new JCheckBox("Candied"); bottom = new TextField(10); BS = new JButton("Build My Salad!"); reset = new JButton("Reset"); sizeborder = new TitledBorder(BorderFactory.createTitledBorder("Size")); ingborder = new TitledBorder(BorderFactory.createTitledBorder("Ingredients")); Westpanel.setLayout(new GridLayout(0, 1)); Westpanel.setBorder(sizeborder); Westpanel.add(small); Westpanel.add(medium); Westpanel.add(large); Centerpanel.setLayout(new GridLayout(3, 3)); Centerpanel.setBorder(ingborder); Centerpanel.add(tom); Centerpanel.add(bac); Centerpanel.add(let); Centerpanel.add(kal); Centerpanel.add(che); Centerpanel.add(egg); Centerpanel.add(can); Centerpanel.add(on); add(Westpanel,BorderLayout.WEST); // add(Northpanel,BorderLayout.NORTH); add(Centerpanel,BorderLayout.CENTER); // add(Southpanel,BorderLayout.SOUTH); setBounds(50, 50, 400, 400); setLayout(new BorderLayout()); setTitle("My Salad Store"); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub } }
错误定位
- 核心问题:组件添加顺序错误。你先调用
add(Westpanel, BorderLayout.WEST)和add(Centerpanel, BorderLayout.CENTER)添加了面板,之后才调用setLayout(new BorderLayout())。这会重置JFrame的布局管理器,导致之前添加的组件被清空——新的布局管理器初始化时不会保留已添加的组件。 - 额外说明:JFrame的默认布局管理器就是BorderLayout,其实你完全不需要手动调用
setLayout(new BorderLayout()),这步操作属于画蛇添足,反而引发了问题。
解决方法
调整代码顺序,要么把setLayout(new BorderLayout())移到添加组件之前,要么直接删除这行代码。以下是修正后的构造函数示例:
public Lab3() { // 先设置布局(可选,因为默认就是BorderLayout) setLayout(new BorderLayout()); Westpanel = new JPanel(); Centerpanel = new JPanel(); // ... 其他组件初始化代码不变 ... // 添加组件到窗口 add(Westpanel,BorderLayout.WEST); // add(Northpanel,BorderLayout.NORTH); add(Centerpanel,BorderLayout.CENTER); // add(Southpanel,BorderLayout.SOUTH); setBounds(50, 50, 400, 400); setTitle("My Salad Store"); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
或者更简单的方式,直接删除setLayout(new BorderLayout())这一行,因为JFrame默认就使用BorderLayout布局。
内容的提问来源于stack exchange,提问作者Chamberrys
相关产品推荐
相关产品推荐

