我尝试过很多东西,但似乎没什么用。当我按下逃生时,有人可以帮我让这个程序退出吗?我对Threads没有多少经验,所以这可能是我的一个缺点。
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Main implements ActionListener {
public static boolean start = false;
public static void Start() {
final JFrame frame = new JFrame();
JPanel panel = new JPanel();
JLabel label = new JLabel("Choose Action:");
JLabel label2 = new JLabel("Hello");
JButton button1 = new JButton("Start");
button1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Robot robot = null;
try {
robot = new Robot();
} catch (AWTException e1) {
e1.printStackTrace();
}
start = true;
System.out.println("Pressed");
while(start) {
robot.keyPress(KeyEvent.VK_W);
try{
Thread.sleep(1);
}
catch(Exception ex) {
}
robot.keyRelease(KeyEvent.VK_W);
try{
Thread.sleep(150);
}
catch(Exception ex) {
}
robot.keyPress(KeyEvent.VK_S);
try{
Thread.sleep(1);
}
catch(Exception ex) {
}
robot.keyRelease(KeyEvent.VK_S);
try{
Thread.sleep(150);
}
catch(Exception ex) {
}
robot.keyPress(KeyEvent.VK_A);
try{
Thread.sleep(1);
}
catch(Exception ex) {
}
robot.keyRelease(KeyEvent.VK_A);
try{
Thread.sleep(150);
}
catch(Exception ex) {
}
robot.keyPress(KeyEvent.VK_D);
try{
Thread.sleep(1);
}
catch(Exception ex) {
}
robot.keyRelease(KeyEvent.VK_D);
try{
Thread.sleep(150);
}
catch(Exception ex) {
}
}
}
} );
JButton button2 = new JButton("Exit");
button2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
start = false;
frame.dispose();
System.exit(0);
}
} );
frame.setTitle("Test");
frame.setSize(350, 100);
frame.setResizable(false );
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.add(panel);
panel.add(label);
panel.add(button1);
panel.add(button2);
panel.add(label2, BorderLayout.SOUTH);
}
public static void main (String args[]) throws InterruptedException {
Start();
}
@Override
public void actionPerformed(ActionEvent arg0) {
}
}
老实说我在这里不知所措。提前感谢任何帮助。
答案 0 :(得分:2)
处理所有GUI
事件的java中的主线程称为事件调度线程或简称EDT。因此,EDT应始终保持空闲,以便它可以处理和服务所有请求。如果您在EDT中运行无限循环或执行长时间运行的任务(如睡眠),则将阻止所有GUI事件。用户界面将冻结。
在你的代码中,你在actionListener
内运行一个无限循环,因此EDT被困在该循环中,无法处理其他UI事件。
如果您需要infinite loop
这样的功能,请使用SwingWorker
。
SwingWorker
允许您在单独的后台线程中运行长时间运行的任务,保持EDT免费。
这是使用button1
的{{1}} actionListener
的代码。粘贴这个,看看。唯一的问题是它会为每次点击开始按钮创建一个新的SwingWorker
,但您可以通过在点击按钮后禁用该按钮来轻松解决这个问题
SwingWorker
答案 1 :(得分:0)
我不确定Robot
我们的用途,但抓住关键事件并对其做出回应的最简单方法是通过key bindings API
GUI编程是关于响应可能在任何时间和任何序列发生的事件,通常是通过使用观察者模式向您传递事件。也就是说,您注册了兴趣,当事件发生时,您会收到通知,您不需要做任何其他事情。
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ClickOfDeath {
public static void main(String[] args) {
new ClickOfDeath();
}
private KeyTask keyTask;
private JTextArea textArea;
public ClickOfDeath() {
EventQueue.invokeLater(
new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JPanel buttons = new JPanel();
final JButton type = new JButton("Start");
type.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
textArea.requestFocusInWindow();
if (keyTask == null) {
type.setText("Stop");
keyTask = new KeyTask();
new Thread(keyTask).start();
} else {
keyTask.stop();
keyTask = null;
type.setText("Start");
}
}
});
JButton close = new JButton(new CloseAction());
InputMap im = close.getInputMap(JButton.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = close.getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape");
am.put("escape", new CloseAction());
buttons.add(type);
buttons.add(close);
textArea = new JTextArea(10, 20);
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(textArea));
frame.add(buttons, BorderLayout.SOUTH);
frame.getRootPane().setDefaultButton(close);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class KeyTask implements Runnable {
private volatile boolean keepRuning = true;
@Override
public void run() {
try {
Robot bot = new Robot();
bot.setAutoDelay(40);
while (keepRuning) {
bot.keyPress(KeyEvent.VK_SHIFT);
type(bot, KeyEvent.VK_S);
bot.keyRelease(KeyEvent.VK_SHIFT);
type(bot, KeyEvent.VK_W);
type(bot, KeyEvent.VK_I);
type(bot, KeyEvent.VK_N);
type(bot, KeyEvent.VK_G);
type(bot, KeyEvent.VK_SPACE);
type(bot, KeyEvent.VK_I);
type(bot, KeyEvent.VK_S);
type(bot, KeyEvent.VK_SPACE);
type(bot, KeyEvent.VK_A);
type(bot, KeyEvent.VK_W);
type(bot, KeyEvent.VK_E);
type(bot, KeyEvent.VK_S);
type(bot, KeyEvent.VK_O);
type(bot, KeyEvent.VK_M);
type(bot, KeyEvent.VK_E);
type(bot, KeyEvent.VK_PERIOD);
type(bot, KeyEvent.VK_PERIOD);
type(bot, KeyEvent.VK_PERIOD);
}
} catch (AWTException exp) {
exp.printStackTrace();
}
}
public void stop() {
keepRuning = false;
}
protected void type(Robot bot, int keyCode) {
bot.keyPress(keyCode);
bot.keyRelease(keyCode);
}
}
public class CloseAction extends AbstractAction {
public CloseAction() {
putValue(NAME, "Close");
}
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
}
Swing是一个单线程环境,也就是说,Swing在自己的线程中运行。阻止该线程的任何操作或操作都将阻止Swing将新事件分派给已注册的侦听器。