Я пытаюсь отключить поведение клавиши ALT по умолчанию в Windows Look and Feel, когда фокус JTextArea сфокусирован, а во фрейме установлено JMenu.По умолчанию происходит то, что меню получает фокус клавиатуры, и поэтому вы не можете продолжать печатать там.
Моей первой попыткой было захватить одиночные нажатия ALT, добавив ключ в JTextArea InputMap:
//Disable ALT key presses when the textarea is focused
jta.getInputMap(javax.swing.JComponent.WHEN_FOCUSED).put(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ALT, 0, true), "ALTKEY");
jta.getActionMap().put("ALTKEY", new javax.swing.AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
System.out.println("Performed");
}
});
Я заметил, что это работало, как и ожидалось, на некоторых сторонних виртуальных машинах, но не в последней версии Oracle 1.8.0_211
Затем я попытался использовать ключевые прослушиватели из компонента AWT и использовать событие до того, как оно достигнет другогокомпоненты.
//Disable ALT key presses when the textarea is focused, second attempt
jta.addKeyListener(new java.awt.event.KeyListener(){
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == java.awt.event.KeyEvent.VK_ALT){
System.out.println("Pressed");
e.consume();
}
}
@Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == java.awt.event.KeyEvent.VK_ALT){
System.out.println("Released");
e.consume();
}
}
@Override
public void keyTyped(KeyEvent e) {
if(e.getKeyCode() == java.awt.event.KeyEvent.VK_ALT){
System.out.println("Typed");
e.consume();
}
}
});
Не повезло.
Наконец, я попытался изменить ключ, используемый для создания ярлыков меню, и полностью избавиться от этого раздражающего поведения ALT:
//Disable the ALT for the Mnemonic and put CTRL:
int[] ints = {java.awt.event.KeyEvent.CTRL_MASK};
javax.swing.UIManager.put("Menu.shortcutKeys", ints);
Это позволило избежать использования сочетаний клавиш с клавишей ALT (и CTRL работал отлично), но не помешало стандартному поведению, когда делается одно нажатие клавиши ALT.
Изменение L & F на другие платформы или нетесли установить его в Windows, то это решит проблему, но, конечно, это изменит внешний вид всей Программы.
Думаю, я что-то делаюЯ ошибся, но изменение InputMap или добавление KeyListeners сработало для сторонней виртуальной машины, поэтому я начинаю думать, что это может быть ошибкой.
Любые идеи о том, как найти того, кто слушаетALT нажимает клавишу и избегает этого?Есть ли способ настроить L & F или посмотреть, какова его конфигурация?
Вот полный код теста:
public class JMenubarAltTest extends javax.swing.JFrame{
private static final long serialVersionUID = 1L;
public JMenubarAltTest(){
super();
//Disable the ALT for the Mnemonic and put CTRL key instead:
int[] ints = {java.awt.event.KeyEvent.CTRL_MASK};
javax.swing.UIManager.put("Menu.shortcutKeys", ints);
//Put the platform L&F, in my case I need this to work in Windows
try {
javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException e1) {
e1.printStackTrace();
}
this.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
//Create a random menu with some random items
javax.swing.JMenuBar jmb = new javax.swing.JMenuBar();
javax.swing.JMenu jm1 = new javax.swing.JMenu("menu1");
jm1.setMnemonic(java.awt.event.KeyEvent.VK_M);
jm1.add(new javax.swing.JMenuItem("item1"));
jm1.add(new javax.swing.JMenuItem("item2"));
jm1.add(new javax.swing.JMenuItem("item3"));
javax.swing.JMenu jm2 = new javax.swing.JMenu("menu1");
jm2.setMnemonic(java.awt.event.KeyEvent.VK_E);
jm2.add(new javax.swing.JMenuItem("item1"));
jm2.add(new javax.swing.JMenuItem("item2"));
jm2.add(new javax.swing.JMenuItem("item3"));
jmb.add(jm1);
jmb.add(jm2);
this.setJMenuBar(jmb);
//Get a JTextArea to show what happens with the focus
javax.swing.JTextArea jta = new javax.swing.JTextArea();
//Disable ALT key presses when the textarea is focused
jta.getInputMap(javax.swing.JComponent.WHEN_FOCUSED).put(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ALT, 0, true), "ALTKEY");
jta.getActionMap().put("ALTKEY", new javax.swing.AbstractAction() {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
System.out.println("Performed");
}
});
//Disable ALT key presses when the textarea is focused, second attempt
jta.addKeyListener(new java.awt.event.KeyListener(){
@Override
public void keyPressed(java.awt.event.KeyEvent e) {
if(e.getKeyCode() == java.awt.event.KeyEvent.VK_ALT){
System.out.println("Pressed");
e.consume();
}
}
@Override
public void keyReleased(java.awt.event.KeyEvent e) {
if(e.getKeyCode() == java.awt.event.KeyEvent.VK_ALT){
System.out.println("Released");
e.consume();
}
}
@Override
public void keyTyped(java.awt.event.KeyEvent e) {
if(e.getKeyCode() == java.awt.event.KeyEvent.VK_ALT){
System.out.println("Typed");
e.consume();
}
}
});
this.getContentPane().add(jta);
this.pack();
this.setSize(200, 200);
this.setVisible(true);
}
public static void main(java.lang.String[] args){
new JMenubarAltTest();
}
}