2009-03-20 11 views
8

W jaki sposób otrzymasz kod VK z znaku będącego literą? Wygląda na to, że powinieneś być w stanie zrobić coś w rodzaju javax.swing.KeyStroke.getKeyStroke('c').getKeyCode(), ale to nie działa (wynikiem jest zero). Każdy wie, jak zdobyć klucz, jeśli już posiadasz KeyEvent, ale co jeśli chcesz zamienić znaki na VK? Nie jestem zainteresowany zdobyciem kodu FK dla dziwnych postaci, tylko [A-Z], [a-z], [0-9].Uzyskaj identyfikator VK z dowolnego znaku w języku Java

Kontekst ten problem -------- Wszystkie samouczki Robot widziałem zakładać programiści lubią przeliterować słowa wysyłając naciśnięć klawiszy z kodami VK:

int keyInput[] = { 
     KeyEvent.VK_D, 
     KeyEvent.VK_O, 
     KeyEvent.VK_N, 
     KeyEvent.VK_E 
    };//end keyInput array 

Zadzwoń do mnie leniwy, ale nawet z Eclipse to nie jest sposób na wykorzystanie TDD na GUI. Jeśli ktokolwiek zda sobie sprawę z klasy podobnej do robota, która pobiera ciągi, a następnie symuluje dane wejściowe użytkownika dla tych ciągów znaków (używam FEST), chciałbym to wiedzieć.

Odpowiedz

5

Może to brzydko Hack:

Map<String, Integer> keyTextToCode = new HashMap<String, Integer>(256); 
Field[] fields = KeyEvent.class.getDeclaredFields(); 
for (Field field : fields) { 
    String name = field.getName(); 
    if (name.startsWith("VK_")) { 
     keyTextToCode.put(name.substring("VK_".length()).toUpperCase(), 
          field.getInt(null)); 
    } 
} 

keyTextToCode będzie zawierało odwzorowanie z łańcuchów (na przykład "a" lub "PAGE_UP") do vk kody.

+0

+1 bardzo dobrze, zauważ, że brak obsługi wyjątków – dfa

1

Nie sądzę, że jest na to prosta odpowiedź.

Najpierw zdaj sobie sprawę, że java ma dwa bajty i nie ma prawie 2^16 zdefiniowanych KeyEvent.VK_. Tak więc będą znaki, dla których nie można wygenerować KeyEvent, aby uzyskać ten wynik.

Również C i c oraz Ç i ç mają ten sam KeyEvent.getKeyCode() == KeyEvent.VK_C.

4
AWTKeyStroke.getAWTKeyStroke("C").getKeyCode(); 
6
AWTKeyStroke.getAWTKeyStroke('c').getKeyCode(); 

Lekko wyjaśnienie Pace's answer. Powinny to być pojedyncze cudzysłowy (reprezentujące znak), a nie podwójne cudzysłowy (reprezentujące ciąg znaków).

Korzystanie z podwójnych cudzysłowów spowoduje zgłoszenie wyjątku java.lang.IllegalArgumentException (niepoprawnie sformatowany ciąg).

1

Odpowiedź Adama Paynter (odpowiedź na pytanie Convert String to KeyEvents) również powinna tutaj zadziałać. Prosty, ale działający pomysł to mieć duży przełącznik podobny do następującego:

public void type(char character) { 
    switch (character) { 
    case 'a': doType(VK_A); break; 
    case 'b': doType(VK_B); break; 
    case 'c': doType(VK_C); break; 
    case 'd': doType(VK_D); break; 
    case 'e': doType(VK_E); break; 
    // ... 
    case 'A': doType(VK_SHIFT, VK_A); break; 
    case 'B': doType(VK_SHIFT, VK_B); break; 
    case 'C': doType(VK_SHIFT, VK_C); break; 
    // ... 
    } 
} 

Zobacz oryginalną odpowiedź dla całego wpisu (łącznie z otaczającą klasą narzędzi).

2

Używam następujący kod duże litery i cyfry w klasie napisałem przedłużyć Robot:


public void typeLetterOrNumber(char c) { 
    if(Character.isLetter(c)) { 
     keyPress((int)c); 
     keyRelease((int)c); 
    } 
    else if(Character.isDigit(c)) { 
     keyPress(48+(int)c); 
     keyRelease(48+(int)c); 
    } 
} 

Zasadniczo, po prostu spojrzał na KeyEvent.VK_whatever wartości i zrobił odpowiednią matematykę do zrekompensowania w moim kodzie.

+0

Bardzo sprytny, dzięki za napiwek !! –

0

Istnieją 2 sposoby znalazłem:

A. użyć obejście z JButton.setMnemonic, getMnemonic:

javax.swing.JButton but = new javax.swing.JButton(); 
but.setMnemonic(charVkValue); 
int intVkValue = but.getMnemonic()); 

B. Pobierz open source jdk i zobaczyć swoją metodę AbstractButton.setMnemonic (char). Ten kod jest licencjonowany na licencji GPL2, ale te 4 linie są generalnie takie same jak w przypadku odpowiedzi za pomocą "keyPress (48+ (int) c)".

http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Core/swing/javax/swing/AbstractButton.java.htm

1

Jeśli głównym celem jest, aby pisać litery tak szybko jak to możliwe, można zrobić to, co zrobiłem, co było napisać ciąg do schowka, a potem po prostu użyć klasy Robot wejść Ctrl + V.

static void type(String s) { 
    Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(s), null); 
    robot.setAutoDelay(30); 
    robot.keyPress(VK_CONTROL); 
    robot.keyPress(VK_V); 
    robot.keyRelease(VK_CONTROL); 
    robot.keyRelease(VK_V); 
} 

Istnieje kilka innych funkcji w schowku systemowym, które pozwalają na zapisywanie i przywracanie dowolnych danych w schowku, na wypadek, gdyby było to konieczne. Jak dobrze, jeśli chcesz kontrolować prędkość pomiędzy poszczególnymi postaciami, możesz umieścić każdą ze skrzynek w schowku pojedynczo, za pomocą pętli foreach.

Powiązane problemy