Do I need to use layout managers to do that ?
short answer: yes :-)
Longer answer: the menu/-bar is a bit special in that some layoutManagers don't do as one (read: me) would expect. Simplest that comes to mind is a one-row 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);
The sanity check demonstrates that the JMenu has its own ideas about how they are layout out: the content is always leading-aligned (the exact distance is LAF and is- or not-topLevelMenu). That's hard-coded in BasicMenuItem.paintMenuItem, internally using the MenuItemLayoutHelper.
So the simplest manager does size and locate them as expected, but can't do anything in centering the individual items.
If centering is needed, you can use a trick (not recommended, though [1]): based on the implementation details that
- the default layoutManger is-a BoxLayout and
- a topLevelMenu has a maxSize == prefSize
you can add glues before/after each item:
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());
With that, they appear centered and evenly distributed across the menubar width: the (could-be, depends on requirement) drawback is that the menus are sized at their pref, that is don't fill the entire bar.
[1] same effect is doable cleanly, without relying on implemetation details, with a powerful-enough manger, like f.i. MigLayout
bar.setLayout(new MigLayout("fill, insets 0", "[center]"));