Ich möchte einen String in KeyEvent umwandeln, um so etwas zu tun:
writeKeyboard(myBot,"abcd");
public void writeKeyboard(Robot bot, String st){
char[] arr = arr.toCharArray();
int i = arr.length();
int j = 0;
int keycode;
while (j<i) {
keycode = arr[j].something;
bot.keyPress(keycode);
bot.keyRelease(keycode);
j++;
}
}
Ich glaube nicht, dass es darauf eine einfache Antwort gibt. Eine ähnliche Frage wurde hier schon einmal gestellt: stackoverflow.com/questions/664896/…
– Aaron
8. August 09 um 10:52 Uhr
Adam Paynter
Ich benutze im Grunde ein verherrlichtes switch Erklärung. Einfach und schnell:
import static java.awt.event.KeyEvent.*;
public class Keyboard {
private Robot robot;
public static void main(String... args) throws Exception {
Keyboard keyboard = new Keyboard();
keyboard.type("Hello there, how are you?");
}
public Keyboard() throws AWTException {
this.robot = new Robot();
}
public Keyboard(Robot robot) {
this.robot = robot;
}
public void type(CharSequence characters) {
int length = characters.length();
for (int i = 0; i < length; i++) {
char character = characters.charAt(i);
type(character);
}
}
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 'f': doType(VK_F); break;
case 'g': doType(VK_G); break;
case 'h': doType(VK_H); break;
case 'i': doType(VK_I); break;
case 'j': doType(VK_J); break;
case 'k': doType(VK_K); break;
case 'l': doType(VK_L); break;
case 'm': doType(VK_M); break;
case 'n': doType(VK_N); break;
case 'o': doType(VK_O); break;
case 'p': doType(VK_P); break;
case 'q': doType(VK_Q); break;
case 'r': doType(VK_R); break;
case 's': doType(VK_S); break;
case 't': doType(VK_T); break;
case 'u': doType(VK_U); break;
case 'v': doType(VK_V); break;
case 'w': doType(VK_W); break;
case 'x': doType(VK_X); break;
case 'y': doType(VK_Y); break;
case 'z': doType(VK_Z); 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;
case 'D': doType(VK_SHIFT, VK_D); break;
case 'E': doType(VK_SHIFT, VK_E); break;
case 'F': doType(VK_SHIFT, VK_F); break;
case 'G': doType(VK_SHIFT, VK_G); break;
case 'H': doType(VK_SHIFT, VK_H); break;
case 'I': doType(VK_SHIFT, VK_I); break;
case 'J': doType(VK_SHIFT, VK_J); break;
case 'K': doType(VK_SHIFT, VK_K); break;
case 'L': doType(VK_SHIFT, VK_L); break;
case 'M': doType(VK_SHIFT, VK_M); break;
case 'N': doType(VK_SHIFT, VK_N); break;
case 'O': doType(VK_SHIFT, VK_O); break;
case 'P': doType(VK_SHIFT, VK_P); break;
case 'Q': doType(VK_SHIFT, VK_Q); break;
case 'R': doType(VK_SHIFT, VK_R); break;
case 'S': doType(VK_SHIFT, VK_S); break;
case 'T': doType(VK_SHIFT, VK_T); break;
case 'U': doType(VK_SHIFT, VK_U); break;
case 'V': doType(VK_SHIFT, VK_V); break;
case 'W': doType(VK_SHIFT, VK_W); break;
case 'X': doType(VK_SHIFT, VK_X); break;
case 'Y': doType(VK_SHIFT, VK_Y); break;
case 'Z': doType(VK_SHIFT, VK_Z); break;
case '`': doType(VK_BACK_QUOTE); break;
case '0': doType(VK_0); break;
case '1': doType(VK_1); break;
case '2': doType(VK_2); break;
case '3': doType(VK_3); break;
case '4': doType(VK_4); break;
case '5': doType(VK_5); break;
case '6': doType(VK_6); break;
case '7': doType(VK_7); break;
case '8': doType(VK_8); break;
case '9': doType(VK_9); break;
case '-': doType(VK_MINUS); break;
case '=': doType(VK_EQUALS); break;
case '~': doType(VK_SHIFT, VK_BACK_QUOTE); break;
case '!': doType(VK_EXCLAMATION_MARK); break;
case '@': doType(VK_AT); break;
case '#': doType(VK_NUMBER_SIGN); break;
case '$': doType(VK_DOLLAR); break;
case '%': doType(VK_SHIFT, VK_5); break;
case '^': doType(VK_CIRCUMFLEX); break;
case '&': doType(VK_AMPERSAND); break;
case '*': doType(VK_ASTERISK); break;
case '(': doType(VK_LEFT_PARENTHESIS); break;
case ')': doType(VK_RIGHT_PARENTHESIS); break;
case '_': doType(VK_UNDERSCORE); break;
case '+': doType(VK_PLUS); break;
case 't': doType(VK_TAB); break;
case 'n': doType(VK_ENTER); break;
case '[': doType(VK_OPEN_BRACKET); break;
case ']': doType(VK_CLOSE_BRACKET); break;
case '\': doType(VK_BACK_SLASH); break;
case '{': doType(VK_SHIFT, VK_OPEN_BRACKET); break;
case '}': doType(VK_SHIFT, VK_CLOSE_BRACKET); break;
case '|': doType(VK_SHIFT, VK_BACK_SLASH); break;
case ';': doType(VK_SEMICOLON); break;
case ':': doType(VK_COLON); break;
case ''': doType(VK_QUOTE); break;
case '"': doType(VK_QUOTEDBL); break;
case ',': doType(VK_COMMA); break;
case '<': doType(VK_SHIFT, VK_COMMA); break;
case '.': doType(VK_PERIOD); break;
case '>': doType(VK_SHIFT, VK_PERIOD); break;
case "https://stackoverflow.com/": doType(VK_SLASH); break;
case '?': doType(VK_SHIFT, VK_SLASH); break;
case ' ': doType(VK_SPACE); break;
default:
throw new IllegalArgumentException("Cannot type character " + character);
}
}
private void doType(int... keyCodes) {
doType(keyCodes, 0, keyCodes.length);
}
private void doType(int[] keyCodes, int offset, int length) {
if (length == 0) {
return;
}
robot.keyPress(keyCodes[offset]);
doType(keyCodes, offset + 1, length - 1);
robot.keyRelease(keyCodes[offset]);
}
}
Wenn Sie eine benutzerdefinierte Schlüsseltypisierung wünschen, können Sie die Klasse erweitern und die überschreiben type(char) Methode. Beispielsweise:
import static java.awt.event.KeyEvent.*;
public class WindowUnicodeKeyboard extends Keyboard {
private Robot robot;
public WindowUnicodeKeyboard(Robot robot) {
super(robot);
this.robot = robot;
}
@Override
public void type(char character) {
try {
super.type(character);
} catch (IllegalArgumentException e) {
String unicodeDigits = String.valueOf(Character.getCodePoint(character));
robot.keyPress(VK_ALT);
for (int i = 0; i < unicodeDigits.length(); i++) {
typeNumPad(Integer.parseInt(unicodeDigits.substring(i, i + 1)));
}
robot.keyRelease(VK_ALT);
}
}
private void typeNumPad(int digit) {
switch (digit) {
case 0: doType(VK_NUMPAD0); break;
case 1: doType(VK_NUMPAD1); break;
case 2: doType(VK_NUMPAD2); break;
case 3: doType(VK_NUMPAD3); break;
case 4: doType(VK_NUMPAD4); break;
case 5: doType(VK_NUMPAD5); break;
case 6: doType(VK_NUMPAD6); break;
case 7: doType(VK_NUMPAD7); break;
case 8: doType(VK_NUMPAD8); break;
case 9: doType(VK_NUMPAD9); break;
}
}
}
Natürlich gibt es Raum für Verbesserungen, aber Sie verstehen schon.
Tolles Beispiel, denken Sie daran, wenn Sie dies verwenden, um einen statischen Import für die Tastencodes zu haben: import static java.awt.event.KeyEvent.*;
– Klogg
12. November 12 um 12:49 Uhr
@klogd Ich habe den statischen Import zum Beispielcode hinzugefügt, da ich ihn auch vermisst habe.
– Dämon
18. Juli 13 um 12:02 Uhr
Führt dies auf der Azerty- und Qwerty-Tastatur zu demselben Ergebnis?
– sliders_alpha
13. September 13 um 11:36 Uhr
Auf meinem Windows 7 x64 mit JDK 1.7.0_25 musste ich die Zeile für den Doppelpunkt in die Groß-/Kleinschreibung „:“ ändern: doType(VK_SHIFT, VK_SEMICOLON); brechen; Ansonsten eine super Lösung!
– Parag Doke
28. Oktober 13 um 6:10 Uhr
Toller Code, danke! Dies funktioniert jedoch nicht für alle Tasten, die 2 gedrückte Tastenkombinationen wie !, @, $, % usw. erfordern, da sie ursprünglich Shift + 1, Shift + 2 usw. sind
– Prophet
4. Juli 15 um 20:37 Uhr
Carl Bosch
Ich habe die Zwischenablage verwendet, um das Problem zu lösen …
instance ist eine Klasse, die die ClipBoardOwner-Schnittstelle implementiert, siehe docs.oracle.com/javase/6/docs/api/java/awt/datatransfer/…, java.awt.datatransfer.ClipboardOwner), habe ich meine Antwort so bearbeitet, dass sie ausführlicher ist
– Carl Bosch
22. August 13 um 11:38 Uhr
Dies ist meiner Meinung nach die beste Lösung, da sie KEINE weitere Java-Datei enthält.
– Nicholas DiPiazza
5. Februar 14 um 20:38 Uhr
clipboard.setContents(stringSelection, clipboardOwner); sollte wohl sein clipboard.setContents(stringSelection, stringSelection);
Sie können dies einfach über die Java-Reflection-API tun:
public void writeKeyboard(Robot bot, String st) {
String upperCase = st.toUpperCase();
for(int i = 0; i < upperCase.length(); i++) {
String letter = Character.toString(upperCase.charAt(i));
String code = "VK_" + letter
Field f = KeyEvent.class.getField(code);
int keyEvent = f.getInt(null);
bot.press(keyEvent);
bot.release(keyEvent);
}
}
Dies ist angemessen, aber nur für die Zeichen, die nicht erforderlich sind Shift während der gewünschten Tasteneingabe gedrückt werden.
– Kryptor
31. August 17 um 11:42 Uhr
Ryan Hilbert
Dazu habe ich kürzlich eine Klasse geschrieben. Es gibt den Alt-Code jedes Zeichens ein, anstatt die Tastenkombination für jeden Fall einzeln herauszufinden. Nicht die schnellste Lösung, aber sie ist prägnant und funktioniert für eine Vielzahl von Charakteren.
import java.awt.AWTException;
import java.awt.Robot;
import static java.awt.event.KeyEvent.VK_ALT;
import static java.awt.event.KeyEvent.VK_NUMPAD0;
public class Altbot extends Robot{
Altbot()throws AWTException{}
public void type(CharSequence cs){
for(int i=0;i<cs.length();i++){
type(cs.charAt(i));
}
}
public void type(char c){
keyPress(VK_ALT);
keyPress(VK_NUMPAD0);
keyRelease(VK_NUMPAD0);
String altCode=Integer.toString(c);
for(int i=0;i<altCode.length();i++){
c=(char)(altCode.charAt(i)+'0');
//delay(20);//may be needed for certain applications
keyPress(c);
//delay(20);//uncomment if necessary
keyRelease(c);
}
keyRelease(VK_ALT);
}
}
So habe ich es geschafft, alle verfügbaren Schlüssel zu verwenden. Erstellen Sie eine Karte und füllen Sie die Karte mit der Methode fillKeyMap. Jetzt können Sie die String-Darstellung von Tastenereignissen verwenden und sie mithilfe der Zuordnung wieder in KeyEvent-Codes konvertieren.
/** Create map with string values to integer pairs
*/
public static final void fillKeyMap(Map<String, Integer> into) {
try {
Field[] fields = KeyEvent.class.getDeclaredFields();
for(Field f : fields) {
if(f.getName().startsWith("VK_")) { //we only want these fields
int code = ((Integer)f.get(null)).intValue();
into.put(f.getName().substring(3), code);
}
}
} catch(Exception ex) {}
}
dfa
Ich benutze grundsätzlich die Befehlsmuster wie Rich Seller es in seiner Antwort tut, mit zwei geringfügigen Änderungen der Kürze halber:
Verwendung der Dekorationsmuster für die Wiederverwendung von Instanzen des az-Befehls
Verwendung von Reflektion zum Entfernen von KeyEvent.VK_???
Befehlsschnittstelle:
interface Command {
void pressKey(Robot robot);
}
und der Dekorateur (für Modifikation Nr. 1):
class ShiftCommand implements Command {
private final Command command;
public ShiftCommand(Command command) {
this.command = command;
}
public void pressKey(Robot robot) {
robot.keyPress(KeyEvent.VK_SHIFT);
command.pressKey(robot);
robot.keyRelease(KeyEvent.VK_SHIFT);
}
@Override
public String toString() {
return "SHIFT + " + command.toString();
}
}
Verwenden Sie diesen Helfer (für Modifikation Nr. 2):
public static int getKeyEvent(Character c) {
Field f = KeyEvent.class.getField("VK_" + Character.toUpperCase(c));
f.setAccessible(true);
return (Integer) f.get(null);
}
IN ACHT NEHMEN: Ich behandle hier keine Ausnahmen, dies bleibt Ihnen als Übung überlassen :))
dann füllen Sie den Befehl mit einer for-Schleife:
Map<Character, Command> commandMap = new HashMap<Character, Command>();
for (int i = 'a'; i <= 'z'; i++) {
final Character c = Character.valueOf((char) i);
Command pressKeyCommand = new Command() {
public void pressKey(Robot robot) {
int keyEventCode = getKeyEvent(c);
robot.keyPress(c);
robot.keyRelease(c);
}
@Override
public String toString() {
return String.format("%c", c);
}
};
// 'a' .. 'z'
commandMap.put(c, pressKeyCommand);
// 'A' .. 'Z' by decorating pressKeyCommand
commandMap.put(Character.toUpperCase(c), new ShiftCommand(pressKeyCommand));
}
Testfall
String test = "aaaBBB";
for (int i = 0; i < test.length(); i++) {
System.out.println(commandMap.get(test.charAt(i)));
}
wie erwartet gibt dies aus:
a
a
a
SHIFT + b
SHIFT + b
SHIFT + b
eine Frage
Es ist ein bisschen wie ein Kludge, aber Sie können das verwenden Befehlsmuster Um die Tastenanschläge für jedes Zeichen in der Zeichenfolge zu kapseln, holen Sie sich dann den Befehl für jedes Zeichen der Reihe nach und rufen Sie die Methode auf. Der Vorteil dabei ist, dass Sie die Karte nur einmal einrichten müssen. Der Nachteil ist, dass es immer noch eine Menge Bolierplate beinhaltet:
public interface Command {
void pressKey(Robot bot);
}
//add a command to the map for each keystroke
commandMap.put("A", new Command() {
void pressKey(Robot bot) {
pressWithShift(KeyEvent.VK_A);
}
});
commandMap.put ("a", new Command() {
void pressKey (Robot bot) {
press (KeyEvent.VK_A);
}
});
commandMap.put("B", new Command() {
void pressKey(Robot bot) {
pressWithShift(KeyEvent.VK_B);
}
});
...
//loads more definitions here
//helper methods
private void pressWithShift (Robot bot, KeyEvent event) {
bot.keyPress (KeyEvent.VK_SHIFT);
press(bot, event);
bot.keyRelase(KeyEvent.VK_SHIFT);
}
private void press(Robot bot, KeyEvent event) {
bot.keyPress(event);
bot.keyRelease(event);
}
Dann, um die Karte zu verwenden:
for (int i = 0; i < st.length(); i++) {
String subString = st.substring(i, i + 1);
commandMap.get(subString).pressKey(bot);
}
+1 Dies ist der richtige Ansatz, aber ich denke, es braucht zu viel Boilerplate-Code
– dfa
8. August 09 um 11:26 Uhr
@dfa das tue ich auch, das sollte meiner Meinung nach wirklich alles von einem RobotHelper erledigt werden. Was würden Sie tun, um die Boilerplate zu reduzieren?
– Reicher Verkäufer
8. August 2009 um 11:35 Uhr
.
7844100cookie-checkString in KeyEvents umwandelnyes
Ich glaube nicht, dass es darauf eine einfache Antwort gibt. Eine ähnliche Frage wurde hier schon einmal gestellt: stackoverflow.com/questions/664896/…
– Aaron
8. August 09 um 10:52 Uhr