【问题标题】:run function on JButton press按下 JButton 时运行功能
【发布时间】:2013-09-03 02:55:19
【问题描述】:

我正在尝试在 java 中制作一个程序,该程序使用机器人每隔几秒钟按下一个特定的键。它有一个带有开始和停止按钮的 GUI 和一个标签,告诉它处于哪个状态。到目前为止,我已经完成了所有工作,除了当我单击“开始”时,它会为我的机器人功能运行循环(这是无限的)它没有像我想象的那样启用停止按钮。我知道无限循环的放置位置很愚蠢,但我不确定如何使其正常工作。

我没有做很多 Java 工作,这只是我想尝试的一件有趣的事情,但中途卡住了。任何帮助表示赞赏。

import java.awt.AWTException;
import java.awt.FlowLayout;
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;

public class Main extends JFrame {

    /**
    * 
    */
    private static final long serialVersionUID = 1L;
    private static boolean running = false;;
    private JButton start_button;
    private JButton stop_button;
    private JLabel tl;
    private static int i = 0;
    Robot robot;

    void start() {

        JFrame frame = new JFrame("Helper");
        tl = new JLabel("Running: " + running);
        start_button = new JButton("Start");
        stop_button = new JButton("Stop");
        stop_button.setEnabled(false);
        frame.add(tl);
        frame.add(start_button);
        frame.add(stop_button);
        frame.setSize(300, 100);
        frame.setVisible(true);
        frame.setLayout(new FlowLayout());
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setLocation(400, 400);

        try {
            robot = new Robot();
        } catch (AWTException e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        }
        robot.setAutoDelay(200);

        start_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                start_button.setEnabled(false);
                stop_button.setEnabled(true);
                running = true;
                tl.setText("Running: " + running);
                while (running) {
                    robot_loop(robot);
                }

            }
        });
        stop_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                start_button.setEnabled(true);
                stop_button.setEnabled(false);
                running = false;
                tl.setText("Running: " + running);

            }
        });

    }

    public static void main(String[] args) {
        new Main().start();

    }

    private static void robot_loop(Robot robot) {

        robot.keyPress(KeyEvent.VK_NUMPAD0);
        robot.keyRelease(KeyEvent.VK_NUMPAD0);

        System.out.println("numpad 0 pressed! - " + i);
        i++;

    }

}

【问题讨论】:

  • 这些事件侦听器的 actionPerformed 方法在 Swing 的事件调度线程上调用,并且由于您进入了无限循环,它会导致 GUI 冻结。您可以在您的 actionPerformed 方法内创建一个线程并在新线程内完成您的工作。尽管您遇到的下一个问题是找到一种在用户按下停止按钮时停止线程的好方法。
  • 使用swingtimer insteas

标签: java swing awtrobot


【解决方案1】:

我已将我的评论改编为答案。

这些事件侦听器的 actionPerformed 方法在 Swing 的事件调度线程上调用,并且由于您进入了无限循环,它会导致 GUI 冻结。您可以在您的 actionPerformed 方法内创建一个线程并在新线程内完成您的工作。尽管您遇到的下一个问题是找到一种在用户按下停止按钮时停止线程的好方法。

很酷的是,您已经在代码中获得了执行此操作的所有逻辑。所以让它工作就像改变一样简单:

    start_button.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            start_button.setEnabled(false);
            stop_button.setEnabled(true);
            running = true;
            tl.setText("Running: " + running);
            while (running) {
                robot_loop(robot);
            }

        }
    });

在自己的线程上做你的工作:

    start_button.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            start_button.setEnabled(false);
            stop_button.setEnabled(true);
            running = true;
            tl.setText("Running: " + running);
            Executors.newSingleThreadExecutor().submit(new Runnable() {
                @Override public void run() {
                    while (running) {
                        robot_loop(robot);
                    }
                }
            });
        }
    });

上面的代码使用了执行器框架(java.util.concurrent.*),而不是直接创建一个线程。 nachokk 建议的另一种选择是使用计时器java.util.Timerjavax.swing.Timer(在这种情况下应该可以)。

【讨论】:

  • 这太完美了!谢谢您的帮助!我唯一没有的挫败感是在你停止后它会额外按下一次,但这真的没什么大不了的。感谢您的帮助!
【解决方案2】:

你可以用SwingTimer做这样的事情

        int delay = 400*1000;// you can inject this property 
        ActionListener taskPerformer = new ActionListener(){
              @Override
              public void actionPerformed(ActionEvent evt2) {
                 robot_loop(robot);
              }

        };

            Timer timer = new Timer(delay, taskPerformer);
            timer.start();

【讨论】:

    猜你喜欢
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 2019-08-17
    • 1970-01-01
    相关资源
    最近更新 更多