如何在按ESCAPE时终止程序?

时间:2013-05-26 02:57:53

标签: java

我尝试过很多东西,但似乎没什么用。当我按下逃生时,有人可以帮我让这个程序退出吗?我对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) {

    }
}

老实说我在这里不知所措。提前感谢任何帮助。

2 个答案:

答案 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将新事件分派给已注册的侦听器。

查看Concurrency in Swing