Мой вопрос на самом деле более общий, но я использую действие пользователя, удерживающего клавишу «Alt» и нажимающего «+», в качестве примера, показывающего трудности.

Я работаю с американской английской клавиатурой, на которой есть «=» (нижний регистр) и «+» (верхний регистр) на одной и той же клавише, поэтому, чтобы нажать «Alt +» (как может быть указано в пункте меню), я должны фактически нажать "Alt Shift =". В Java AWT нажатие «Alt Shift =" генерирует событие KeyEvent с нажатием клавиши с кодом клавиши, связанным с клавишей «=», и событие KeyEvent с нажатием клавиши, содержащее символ «±». Таким образом, нет очевидного, надежного способа программно определить, что «Alt» удерживался нажатым, пока была нажата клавиша «+».

Я мог бы сделать внутреннее сопоставление, чтобы исправить это, например, сопоставление «±» с «Alt +» или сопоставление «Shift {keycode for = }» с «+». Однако нет никаких гарантий, что это будет работать на разных раскладках клавиатуры; и это, конечно, не хороший стиль кодирования.

Если кто-нибудь может предложить способ обойти эти проблемы или, возможно, указать код, который уже справился с этой проблемой, я был бы очень признателен.

Спасибо.

5
Kenneth McDonald 28 Мар 2011 в 00:14
Вам нужно решить, хотите ли вы знать, какие клавиши были нажаты или какие клавиши были набраны. Обычно вы должны обнаруживать нажатую клавишу, поскольку клавиша нажата для изменения набранной клавиши на разных клавиатурах, и обычно вам нужно знать, когда набирается клавиша (клавиша нажата и отпущена), а не только когда нажата и пользователь может удерживать клавишу некоторое время.
 – 
David Oliván Ubieto
28 Мар 2011 в 01:25
Привет Дэвид, спасибо за ответ. Я согласен, что мониторинг "keyTyped" был бы лучшим, но, как я уже сказал, это не идентифицирует фактический символ, который пользователь видит на клавиатуре, а это то, что я хочу сделать.
Кроме того, обработка чего-либо например, «Alt-e» проблематичен, так как он не вызывает keyTyped при нажатии клавиши, а мониторинг нажатий «Alt-e Alt-<какой-то другой символ>» действительно болезненный с помощью keyTyped действительно болезненный, так как это может привести к акценту символы.
 – 
Kenneth McDonald
28 Мар 2011 в 22:40

1 ответ

Попробуй это:

if(e.isAltDown())
{
    switch(e.getKeyChar())
    {
        case '+':
            System.out.println("Plus");
        break;
    }
}

Где e — это KeyEvent, и он обрабатывается в методе keyPressed.

Приведенный выше код напечатает Plus, когда вы нажмете ALT+Shift+= на указанной вами клавиатуре.

Полный рабочий код см. в приведенном ниже примере:

import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.UIManager;


public class SwingTest 
{

    private static JFrame frame;

    public static void main(String[] args) throws Exception
    {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            try {
                UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        frame = new JFrame("Event Test");

        Toolkit tk = Toolkit.getDefaultToolkit();  
        int xSize = ((int) tk.getScreenSize().getWidth()/2) + 100;  
        int ySize = ((int) tk.getScreenSize().getHeight()/2) + 50;  

        frame.setSize(xSize,ySize); 
        frame.setLocationRelativeTo(null); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.addKeyListener(new KeyListener() 
        {
            public void keyTyped(KeyEvent e) {
            }

            public void keyReleased(KeyEvent e) {
            }

            public void keyPressed(KeyEvent e) 
            {
                if(e.isAltDown())
                {
                    switch(e.getKeyChar())
                    {
                    case '+':
                        System.out.println("Plus");
                        break;
                    }
                }
            }
        });

        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                frame.setVisible(true);
            }
        });         
    }
}

Надеюсь, это поможет.

2
Favonius 28 Мар 2011 в 22:39
Привет Фавониус, спасибо за подробный ответ. Однако это не сработало в моей системе (OS X 10.6, последнее обновление Java 6 в OS X), поэтому я изменил код, чтобы избавиться от переключателя и просто выполнить «System.out.println(e.getKeyChar( ))" Как и в случае с моим кодом на Scala, выводится символ "±" (маленький + непосредственно над маленьким -; математический символ "плюс-минус"). Вздох.
 – 
Kenneth McDonald
30 Мар 2011 в 23:18
McDonald: Демо было написано на машине с Win Vista и Java 1.6_b18 (не текущей версии). Не уверен насчет OS X. Покопаемся еще какое-то время.
 – 
Favonius
31 Мар 2011 в 07:23
Я бы не беспокоился об этом; Вероятно, Apple добавила слой сопоставления клавиатуры, в котором мне придется покопаться, и в любом случае это не мешает мне. Я как бы ожидаю, что JavaFX 2 в конечном итоге станет фактическим набором пользовательского интерфейса, на который я нацелен, поэтому использование AWT — это просто временное решение, пока JFX 2 не станет общедоступным. Я очень ценю ваше время, но у вас нет причин тратить еще больше времени на то, что не принесет вам пользы.
 – 
Kenneth McDonald
31 Мар 2011 в 23:11