Add accelerator description to JMenuItem in GUI, w

2019-08-28 09:02发布

问题:

I'm trying to set some text to be displayed where the accelerator binding is usually displayed, for a JMenuItem. The demarcated Ctrl+Z text in the following image is an example of what I'm trying to set, for another JMenuItem.

I don't actually want to set an accelerator for this JMenuItem, though. I've poked around the source for several classes, like JMenuItem and BasicMenuItemUI, to no avail. What's the simplest way to achieve this?

Thanks in advance :)

回答1:

I assume the reason you want this is so you can prevent the menu from triggering the undo action a second time, when the key combination is already bound on a component on the frame, but this shouldn't be necessary. If the component consumes the key event, the menu won't detect it.

Here's an example with a JTextArea to see what I mean:

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

JMenuBar menu = new JMenuBar();
frame.setJMenuBar(menu);
JMenu menuEdit = new JMenu("Edit");
menu.add(menuEdit);
JMenuItem menuEditUndo = new JMenuItem("Undo");
menuEdit.add(menuEditUndo);
menuEditUndo.setAccelerator(KeyStroke.getKeyStroke("control Z"));
menuEditUndo.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("menu");
    }
});

JTextArea textArea = new JTextArea(20, 40);
textArea.getInputMap().put(KeyStroke.getKeyStroke("control Z"), "undo");
textArea.getActionMap().put("undo", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("text");
    }
});
frame.add(new JScrollPane(textArea));

frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

Both the text area and the menu item have bound to the same key combo, but pressing Ctrl+Z while the text area has focus prints only "text" and never "menu". I.e., the action does not happen twice. Although this uses a JTextArea, it should be true of any component.