A solução é a classe java.awt.Robot. Exemplo usando uma classe utilitária que eu fiz, uma vez que trabalhar com Robot manualmente é bem chato (mas não deixe de procurar tutoriais e consultar a documentação):
Classe Robo1.java
import static java.awt.event.KeyEvent.VK_ALT;
import static java.awt.event.KeyEvent.VK_TAB;
import java.awt.AWTException;
import java.awt.Robot;
import robot.util.RobotUtils;
public class Robo1 {
public static void main(String[] args) {
Robot robo = null;
try {
robo = new Robot();
} catch (AWTException ex) {
ex.printStackTrace();
return;
}
robo.setAutoDelay(200);
robo.setAutoWaitForIdle(true);
RobotUtils.pressionaTeclasEspeciais(robo, VK_ALT, VK_TAB);
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
RobotUtils.pressionaTeclasEspeciais(robo, VK_ALT, VK_TAB);
}
}
Classe RobotUtils.java (apesar de estar “feinha” funciona)
import java.awt.Robot;
import java.awt.event.KeyEvent;
public class RobotUtils {
public static void digita(final Robot robo, final String texto) {
final char[] digitos = texto.toCharArray();
for (final char c : digitos) {
if (Character.isLetter(c)) {
final int code = Character.toUpperCase(c);
if ((code >= KeyEvent.VK_A) && (code <= KeyEvent.VK_Z)) {
if (Character.isUpperCase(c)) {
RobotUtils.pressionaTeclasEspeciais(robo,
KeyEvent.VK_SHIFT, code);
} else {
RobotUtils.pressionaTecla(robo, code);
}
} else {
RobotUtils.imprimeCaractereEspecial(robo, c);
}
} else if (Character.isDigit(c)) {
RobotUtils.pressionaTecla(robo, c);
} else if (Character.isWhitespace(c)) {
int code = 0;
switch (c) {
case ' ':
code = KeyEvent.VK_SPACE;
break;
case '\n':
code = KeyEvent.VK_ENTER;
break;
case '\t':
code = KeyEvent.VK_TAB;
break;
default:
code = KeyEvent.VK_UNDEFINED;
break;
}
RobotUtils.pressionaTecla(robo, code);
} else {
boolean usaShift = false;
int code = 0;
switch (c) {
case '!':
code = KeyEvent.VK_EXCLAMATION_MARK;
usaShift = true;
break;
case '@':
code = KeyEvent.VK_AT;
usaShift = true;
break;
case '.':
code = KeyEvent.VK_PERIOD;
break;
case ',':
code = KeyEvent.VK_COMMA;
break;
case ':':
code = KeyEvent.VK_COLON;
break;
case ';':
code = KeyEvent.VK_SEMICOLON;
usaShift = true;
break;
case '/':
code = KeyEvent.VK_SLASH;
break;
case '\':
code = KeyEvent.VK_BACK_SLASH;
break;
case '_':
code = KeyEvent.VK_UNDERSCORE;
usaShift = true;
break;
case '?':
code = KeyEvent.VK_SLASH;
usaShift = true;
break;
case '-':
code = KeyEvent.VK_MINUS;
break;
default:
code = 0;
break;
}
if (usaShift) {
RobotUtils.pressionaTeclasEspeciais(robo,
KeyEvent.VK_SHIFT, code);
} else {
RobotUtils.pressionaTecla(robo, code);
}
}
}
}
public static void pressionaEnter(final Robot robo) {
RobotUtils.pressionaTecla(robo, KeyEvent.VK_ENTER);
}
public static void pressionaTecla(final Robot robo, final int code) {
robo.keyPress(code);
robo.keyRelease(code);
}
public static void pressionaTeclasEspeciais(final Robot robo,
final int... codes) {
for (final int code : codes) {
robo.keyPress(code);
}
for (int i = codes.length - 1; i >= 0; i--) {
robo.keyRelease(codes[i]);
}
}
private static void imprimeCaractereEspecial(final Robot robo, final char c) {
int cod = 0;
boolean temAcentoAgudo = false;
boolean temAcentoCircunflexo = false;
boolean temTil = false;
boolean usaShift = false;
switch (c) {
case 'á':
case 'Á':
cod = KeyEvent.VK_A;
usaShift = Character.isUpperCase(c);
temAcentoAgudo = true;
break;
case 'ã':
case 'Ã':
cod = KeyEvent.VK_A;
usaShift = Character.isUpperCase(c);
temTil = true;
break;
case 'â':
case 'Â':
cod = KeyEvent.VK_A;
usaShift = Character.isUpperCase(c);
temAcentoCircunflexo = true;
break;
case 'é':
case 'É':
cod = KeyEvent.VK_E;
usaShift = Character.isUpperCase(c);
temAcentoAgudo = true;
break;
case 'ẽ':
case 'Ẽ':
cod = KeyEvent.VK_E;
usaShift = Character.isUpperCase(c);
temTil = true;
break;
case 'ê':
case 'Ê':
cod = KeyEvent.VK_E;
usaShift = Character.isUpperCase(c);
temAcentoCircunflexo = true;
break;
case 'í':
case 'Í':
cod = KeyEvent.VK_I;
usaShift = Character.isUpperCase(c);
temAcentoAgudo = true;
break;
case 'ĩ':
case 'Ĩ':
cod = KeyEvent.VK_I;
usaShift = Character.isUpperCase(c);
temTil = true;
break;
case 'î':
case 'Î':
cod = KeyEvent.VK_I;
usaShift = Character.isUpperCase(c);
temAcentoCircunflexo = true;
break;
case 'ó':
case 'Ó':
cod = KeyEvent.VK_O;
usaShift = Character.isUpperCase(c);
temAcentoAgudo = true;
break;
case 'õ':
case 'Õ':
cod = KeyEvent.VK_O;
usaShift = Character.isUpperCase(c);
temTil = true;
break;
case 'ô':
case 'Ô':
cod = KeyEvent.VK_O;
usaShift = Character.isUpperCase(c);
temAcentoCircunflexo = true;
break;
case 'ú':
case 'Ú':
cod = KeyEvent.VK_U;
usaShift = Character.isUpperCase(c);
temAcentoAgudo = true;
break;
case 'ũ':
case 'Ũ':
cod = KeyEvent.VK_U;
usaShift = Character.isUpperCase(c);
temTil = true;
break;
case 'û':
case 'Û':
cod = KeyEvent.VK_U;
usaShift = Character.isUpperCase(c);
temAcentoCircunflexo = true;
break;
case 'ñ':
case 'Ñ':
cod = KeyEvent.VK_N;
usaShift = Character.isUpperCase(c);
temTil = true;
break;
}
if (temAcentoAgudo) {
RobotUtils.pressionaTecla(robo, KeyEvent.VK_DEAD_ACUTE);
} else if (temAcentoCircunflexo) {
RobotUtils.pressionaTeclasEspeciais(robo, KeyEvent.VK_SHIFT,
KeyEvent.VK_CIRCUMFLEX);
} else if (temTil) {
RobotUtils.pressionaTecla(robo, KeyEvent.VK_CIRCUMFLEX);
}
if (usaShift) {
RobotUtils.pressionaTeclasEspeciais(robo, KeyEvent.VK_SHIFT, cod);
} else {
RobotUtils.pressionaTecla(robo, cod);
}
}
}
Os métodos são todos estáticos, e devem passar uma instância da classe Robot como argumento para funcionarem.
O método digita(Robot, String) faz com que o robô vá pressionando as teclas correspondentes a uma String (está grande e confuso por causa dos caracteres especiais, e a única solução que encontrei foi essa, que apesar de meio POG, funciona).
O método pressionaEnter(Robot) apenas aperta o Enter.
O método pressionaTecla(Robot, int) aperta determinada tecla, baseando-se no seu código (a partir da classe KeyEvent).
E, por fim, o método pressionaTeclasEspeciais(Robot, int…) usado no exemplo aperta todas as teclas passadas como parâmetros e vai soltando-as na ordem inversa que pressionou.