我正在尝试在 JFrame 中创建一个等距的菜单。通过不等间距的菜单,我的意思是菜单项的宽度随我们放入该菜单的文本而变化。现在,我的菜单看起来像这样:
我希望我的菜单看起来像这样
我可以这样做吗?我需要使用布局管理器来做到这一点吗?
我正在尝试在 JFrame 中创建一个等距的菜单。通过不等间距的菜单,我的意思是菜单项的宽度随我们放入该菜单的文本而变化。现在,我的菜单看起来像这样:
我希望我的菜单看起来像这样
我可以这样做吗?我需要使用布局管理器来做到这一点吗?
我需要使用布局管理器来做到这一点吗?
简短的回答:是的:-)
更长的答案:menu/-bar 有点特别,因为某些 layoutManagers 不像一个(阅读:我)所期望的那样。想到的最简单的是单行 GridLayout:
// sanity check: does grid respect component alignment?
// manager does, but menu internal layout doesn't
JComponent content = new JPanel(new GridLayout(3, 3));
for (int i = 0; i < 9; i++) {
if (i % 2 == 0) {
JMenu menu = new JMenu("menu: " + i);
menu.setBorderPainted(true);
menu.setBorder(BorderFactory.createLineBorder(Color.GREEN));
menu.setHorizontalAlignment(JMenu.CENTER);
content.add(menu);
} else {
JLabel menu = new JLabel("label: " + i);
menu.setBorder(BorderFactory.createLineBorder(Color.GREEN));
menu.setHorizontalAlignment(JMenu.CENTER);
content.add(menu);
}
}
JXFrame frame = wrapInFrame(content, "menuBar with GridLayout");
JMenuBar bar = getMenuBar(frame);
// not surprisingly (after sanity check),
// horizontal align isn't respected in the menubar as well
bar.setLayout(new GridLayout(1, 0));
JMenu menu = new JMenu("some dummy");
menu.setBorderPainted(true);
menu.setBorder(BorderFactory.createLineBorder(Color.GREEN));
menu.setHorizontalAlignment(JMenu.CENTER);
bar.add(menu);
bar.add(new JMenu("other"));
show(frame, 500, 500);
完整性检查表明 JMenu 对它们的布局方式有自己的想法:内容始终是前导对齐的(确切的距离是 LAF 和 is- or not-topLevelMenu)。这是在 BasicMenuItem.paintMenuItem 中硬编码的,内部使用 MenuItemLayoutHelper。
因此,最简单的管理器会按预期对它们进行大小调整和定位,但在将单个项目居中时无能为力。
如果需要居中,您可以使用一个技巧(虽然 [1] 不推荐):基于实现细节
您可以在每个项目之前/之后添加胶水:
JMenu menu = new JMenu("some dummy");
menu.setBorderPainted(true);
menu.setBorder(BorderFactory.createLineBorder(Color.GREEN));
menu.setHorizontalAlignment(JMenu.CENTER);
bar.add(Box.createHorizontalGlue());
bar.add(menu);
bar.add(Box.createHorizontalGlue());
bar.add(new JMenu("other"));
bar.add(Box.createHorizontalGlue());
这样一来,它们就显得居中并均匀分布在菜单栏宽度上:(可能,取决于要求)缺点是菜单的大小是按其偏好设置的,即不会填满整个栏。
[1] 相同的效果是干净的,不依赖于实现细节,具有足够强大的管理器,如 fi MigLayout
bar.setLayout(new MigLayout("fill, insets 0", "[center]"));
您也可以使用 aJToolBar
和 aGridLayout(1, 0)
来获得均匀的间距。
将每个菜单项上的首选大小设置为相同。
jMenu1.setPreferredSize(new java.awt.Dimension(80, 21));
jMenu2.setPreferredSize(new java.awt.Dimension(80, 21));
jMenu3.setPreferredSize(new java.awt.Dimension(80, 21));