此代码的主要目的是一种在JFrame中使用keyListeners的AutoHotKey。 AutoHotKey易于使用,并且可以提供更快的解决方案,但是我出于学习目的而编写此
我正在尝试使我的keyListeners(KeyPressed)之一从机器人keyPress而不是用户keyPress接收输入。我创建了一个Robot对象,并发送了keyPress和keyRelease,但是该程序仍在请求用户输入其他信息。
我要发生的是触发keyPress事件,并让keyListener将其作为用户的输入,并继续执行程序的其余部分,最终将其关闭。
当前代码:
public class Main extends JFrame implements KeyListener {
private static final long serialVersionUID = 7225065896901900132L;
/**
* Aye, I do not recommend storing passwords as plain text if it is for
* something important but here is this code anyway because i'm bored.
*
* Also should not that using a AutoHotKey or any other macro program is way
* easier but i'm using Java because learning amiright
*/
//declaring variables and objects
private static String fileName = "C:/users/21cra/Desktop/rmtinfo.txt";
private static Scanner SC;
private Robot robObject;
public static void main(String[] args) {
//creates JFrame
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Main frame = new Main();
frame.setTitle("Copier");
frame.setResizable(false);
frame.setSize(0, 0);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
public Main() {
//add key listener for this JFrame
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
// try catch for forcing Escape key press
try {
robObject = new Robot();
robObject.keyPress(KeyEvent.VK_ESCAPE);
robObject.keyRelease(KeyEvent.VK_ESCAPE);
System.out.println("press");
} catch (AWTException e1) {
e1.printStackTrace();
}
}
@Override
public void keyPressed(KeyEvent e) {
// declaring variables and objects
String pass = null;
File passFile = new File(fileName);
// try catch for handling next key press
// also copies the first line of any file
try {
SC = new Scanner(new File(fileName));
pass = SC.next();
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_ESCAPE) {
StringSelection stringObj = new StringSelection(pass);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringObj, null);
System.exit(0);
}
System.out.println(pass);
} catch (Exception error) {
System.out.println("Error " + error);
}
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
}
答案 0 :(得分:1)
因此,存在许多问题。为了使KeyListener
生成键事件,其注册到的组件必须是可聚焦的并且具有键盘焦点。最好的时候,这是一件很难的事情。
您正在生成关键事件,然后该窗口将被实现(附加到本机同位体)并在屏幕上可见,这意味着KeyListener
将无法对其进行响应。您需要等到窗口可见并在屏幕上处于活动状态。由于setVisible
仅声明使窗口“应该”可见,因此不能保证该窗口将是活动的并且可用于处理输入事件。您需要某种方法来在setVisible
和击键的产生之间进行延迟。
在这里类似第二个Thread
可能有用...
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
// try catch for forcing Escape key press
try {
Robot robObject = new Robot();
robObject.keyPress(KeyEvent.VK_ESCAPE);
robObject.keyRelease(KeyEvent.VK_ESCAPE);
System.out.println("press");
} catch (AWTException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
t.start();
有关更多详细信息,请参见Concurrency in Java。
所以,真的很基础。它启动一个线程,等待一秒钟,然后触发按键事件。应该把工作做好,这有点脏。
nb:摆动是单线程的,不是线程安全的。永远不要从事件调度线程的上下文之外更新UI
由于KeyListener
如此……令人烦恼,一个更好的解决方案可能是使用Key Bindings API,这将使您更好地控制应生成关键事件的焦点级别。 / p>
也许更像是...
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.Scanner;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Main extends JFrame {
private static final long serialVersionUID = 7225065896901900132L;
/**
* Aye, I do not recommend storing passwords as plain text if it is for
* something important but here is this code anyway because i'm bored.
*
* Also should not that using a AutoHotKey or any other macro program is way
* easier but im using Java because learning amiright
*/
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Main frame = new Main();
frame.setTitle("Copier");
frame.setResizable(false);
frame.setSize(100, 100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
}
// try catch for forcing Escape key press
try {
Robot robObject = new Robot();
robObject.keyPress(KeyEvent.VK_ESCAPE);
robObject.keyRelease(KeyEvent.VK_ESCAPE);
System.out.println("press");
} catch (AWTException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
t.start();
}
});
}
public Main() {
JPanel panel = new JPanel(new BorderLayout());
InputMap inputMap = panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = panel.getActionMap();
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape");
actionMap.put("escape", new EscapeAction());
setContentPane(panel);
}
protected class EscapeAction extends AbstractAction {
private final String fileName = "C:/users/21cra/Desktop/rmtinfo.txt";
@Override
public void actionPerformed(ActionEvent e) {
String pass = null;
File passFile = new File(fileName);
try (Scanner scanner = new Scanner(new File(fileName))) {
pass = scanner.next();
StringSelection stringObj = new StringSelection(pass);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringObj, null);
System.exit(0);
System.out.println(pass);
} catch (Exception error) {
System.out.println("Error " + error);
}
}
}
}