Java中GridBagLayout布局下JButton无法完整显示问题求助
GridBagLayout布局下按钮显示被截断的解决办法
问题
我用GridBagLayout做JPanel的布局,面板里有1个JLabel和2个JButton,结果只有标签能完整显示,按钮的文字被截掉一半,尺寸也比预期小很多。就算用setSize()给按钮指定了尺寸,也完全没用。
问题截图:
相关代码:
public class StartPanel extends JPanel { private int width = 32 * 32; private int height = 32 * 18; // 按钮 private JButton[] buttons; private JButton startButton; private JButton exitButton; // 标签 private JLabel titel; // 其他对象 private PassivThread passivThread; private GridBagLayout gbl; private GridBagConstraints gbc; private Fenster fenster; public StartPanel(PassivThread passivThread) { this.passivThread = passivThread; setPreferredSize(new Dimension(width, height)); setBackground(Color.black); gbl = new GridBagLayout(); gbc = new GridBagConstraints(); setLayout(gbl); loadObjects(); buttonEvents(); setVisible(true); } // 放置组件 private void loadObjects() { startButton = new RoundedBorder("开始游戏", 75); exitButton = new RoundedBorder("返回桌面", 75); buttons = new JButton[2]; buttons[0] = startButton; buttons[1] = exitButton; Font font = new Font("Monospaced", Font.BOLD, 40); titel = new JLabel("Jump 'n' Run"); titel.setFont(font); titel.setForeground(Color.red); titel.setVisible(true); gbc.gridx = 0; gbc.gridy = 0; gbc.gridheight = 2; gbc.insets = new Insets(20, 0, 20, 0); add(titel, gbc); for (int i = 0; i < buttons.length; i++) { buttons[i].setForeground(Color.white); buttons[i].setBackground(null); buttons[i].setFont(font); buttons[i].setBorder(null); buttons[i].setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); buttons[i].setSize(new Dimension(width / 2, 50)); gbc.gridheight = 1; gbc.gridy = 2 + i; add(buttons[i], gbc); } } }
解决思路
GridBagLayout根本不认setSize()设置的尺寸,它只看组件的首选尺寸(preferredSize)和GridBagConstraints里的参数配置,问题出在你没给按钮设置正确的布局约束:
- 加填充和权重参数:给按钮的约束里加上
fill = GridBagConstraints.HORIZONTAL,让按钮能水平填充可用空间;再设置weightx = 1.0,让布局时给按钮分配足够的水平空间,不会挤在一起。 - 替换setSize():
setSize()对GridBagLayout无效,如果要固定按钮大小,用setPreferredSize();如果是自定义的RoundedBorder按钮,得确保它重写了getPreferredSize()方法,能正确算出容纳文字和圆角的尺寸,不然组件不知道自己该占多大地方。 - 调整内边距:给按钮加合适的
insets,上下左右留点空隙,避免文字贴边被截断。
修改后的loadObjects()代码示例:
private void loadObjects() { startButton = new RoundedBorder("开始游戏", 75); exitButton = new RoundedBorder("返回桌面", 75); buttons = new JButton[2]; buttons[0] = startButton; buttons[1] = exitButton; Font font = new Font("Monospaced", Font.BOLD, 40); titel = new JLabel("Jump 'n' Run"); titel.setFont(font); titel.setForeground(Color.red); // 标签的约束:不需要填充,权重设0 gbc.gridx = 0; gbc.gridy = 0; gbc.gridheight = 2; gbc.insets = new Insets(20, 0, 20, 0); gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0; add(titel, gbc); // 按钮的通用约束:水平填充,权重1,加内边距 gbc.gridheight = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 1.0; gbc.insets = new Insets(10, 50, 10, 50); for (int i = 0; i < buttons.length; i++) { buttons[i].setForeground(Color.white); buttons[i].setBackground(null); buttons[i].setFont(font); buttons[i].setBorder(null); buttons[i].setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); // 如果需要固定大小,用这个替代setSize // buttons[i].setPreferredSize(new Dimension(width / 2, 50)); gbc.gridy = 2 + i; add(buttons[i], gbc); } }
内容的提问来源于stack exchange,提问作者NoNameIdea
相关产品推荐
相关产品推荐

