我有一个用户请求添加一个快捷键到子菜单(JMenu),这将允许用户按下快捷键,并有相应的子菜单“折叠”,显示其包含的菜单项。
我不记得曾经见过这样的东西(无论是在Java中还是在任何其他语言中)。我们的应用程序是使用Swing用Java编写的。我们有一些带有加速器的JMenuItems可以很好地工作,但是当我试图在JMenu中添加一个加速器时,我得到了以下异常:
java.lang.Error:没有为JMenu定义setAccelerator()。请改用setMnemonic()。
我已经试过使用MenuDemo了!进一步尝试这一点的代码。
这是我尝试过的:
//a submenu
menu.addSeparator();
submenu = new JMenu("A submenu");
submenu.setMnemonic(KeyEvent.VK_S);
submenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.CTRL_MASK));
最后一行是我添加的那一行,它导致了异常。
我尝试了大量的谷歌搜索,但我所能找到的都是关于如何在JMenuItem中添加加速器的文章。
看起来JMenu本身并不支持这一点。有什么解决方法可以实现这种行为吗?
发布于 2012-10-16 18:54:35
另一种选择是覆盖加速器get/set并重现JMenuItem行为。然后UI将完成剩下的工作。
重要的是触发属性更改,并为加速器提供一致的get/set。此解决方案的优点在于,它还提供了快捷键/快捷键的可视指示。
下面是一小段演示代码:
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestMenu {
protected void initUI() {
JFrame frame = new JFrame(TestMenu.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenuBar bar = new JMenuBar();
JMenu topMenu = new JMenu("Top Menu");
JMenu subMenu = new JMenu("Sub menu") {
private KeyStroke accelerator;
@Override
public KeyStroke getAccelerator() {
return accelerator;
}
@Override
public void setAccelerator(KeyStroke keyStroke) {
KeyStroke oldAccelerator = accelerator;
this.accelerator = keyStroke;
repaint();
revalidate();
firePropertyChange("accelerator", oldAccelerator, accelerator);
}
};
subMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, KeyEvent.CTRL_MASK));
JMenuItem item1 = new JMenuItem("Item 1");
JMenuItem item2 = new JMenuItem("Item 2");
subMenu.add(item1);
subMenu.addSeparator();
subMenu.add(item2);
topMenu.add(subMenu);
bar.add(topMenu);
frame.setJMenuBar(bar);
frame.setSize(400, 300);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new TestMenu().initUI();
}
});
}
}
发布于 2012-10-16 16:09:58
我不认为这是可能的。但是你可以做的是添加一个模拟点击的AbstractAction
。
submenu.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("control U"), "expand");
submenu.getActionMap().put("expand", new AbstractAction("expand") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent evt) {
submenu.doClick();
}
}
);
我希望这也适用于你。
https://stackoverflow.com/questions/12909851
复制相似问题