0

Does anyone know how to control the display of the tiny little arrow that appears on submenus of JMenu?

Can I change it? Can I disable it? Can I move it?

Also, I notice that this arrow doesn't appear on top level JMenus only when they are submenus of other JMenu. This inconsistency annoys me since I have a mix of JMenuItem and JMenu attached to the root of my JMenuBar and so I wish it would always indicate it. Anyway to do this as well?

thanks!

springcorn
  • 611
  • 2
  • 15
  • 28
  • This probably depends on the L&F you are using – Jeffrey Aug 26 '12 at 01:21
  • I am using the MetalLookAndFeel. Can you disable it in a particular look and feel? – springcorn Aug 26 '12 at 01:34
  • *"this arrow doesn't appear on top level JMenus only when they are submenus of other JMenu."* Huh? Can you express that in [code](http://sscce.org/)? – Andrew Thompson Aug 26 '12 at 02:29
  • When menus are added directly to JMenuBar as in myJMenuBar.add(new JMenu("Top Level Menu")) then the little arrow indicating a submenu does not appear. If you however add a JMenu to an already existing JMenu as in myTopLevelJMenu.add(new JMenu("lower level jmenu") then the arrows do appear – springcorn Aug 26 '12 at 02:44

2 Answers2

5

Take a look at the Menu.arrowIcon UI property

No Arrows

(Thanks to AndrewThompson for the test code).

Doining this will effect ALL the menus created AFTER you apply the modifications.

So after you init Look and Feel and before you create any menus call UIManager.getLookAndFeelDefaults().put("Menu.arrowIcon", null);

I'd just like to say I think this is a terrible idea and would highly discourage you from doing it.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
4

this arrow doesn't appear on top level JMenus only when they are submenus of other JMenu.

It seem (monotonously) consistent in its appearance using Metal here.

Menu & sub-menu arrows using Metal PLAF

import javax.swing.*;

public class MenuArrows {

    MenuArrows() {
        JMenuBar mb = new JMenuBar();

        JMenu root1 = new JMenu("Root Menu 1"); 
        JMenu root2 = new JMenu("Root Menu 2"); 

        addSubMenus(root1, 5);
        addSubMenus(root2, 3);

        mb.add(root1);
        mb.add(root2);

        JOptionPane.showMessageDialog(null, mb);
    }

    public void addSubMenus(JMenu parent, int number) {
        for (int i=1; i<=number; i++) {
            JMenu menu = new JMenu("Sub Menu " + i);
            parent.add(menu);

            addSubMenus(menu, number-1);
            addMenuItems(menu, number);
        }
    }

    public void addMenuItems(JMenu parent, int number) {
        for(int i=1; i<=number; i++) {
            parent.add(new JMenuItem("Item " + i));
        }
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                new MenuArrows();
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • @trashgod Saved some typing or copy/pasting. ;) – Andrew Thompson Aug 26 '12 at 07:04
  • I wonder if the `add*()` methods should be `private`; they're called from the constructor, and `addSubMenus()` is a little dangerous. Passing in `Short.MAX_VALUE` (eventually) prints out the name of this site. :-) – trashgod Aug 26 '12 at 07:14
  • 1
    @trashgod Must admit I was thinking more of 'demonstrating the advantage of posting an SSCCE' than good coding technique or answering the ..what *was* the question? – Andrew Thompson Aug 26 '12 at 07:25