在 JButton 按下时运行函数 [英] run function on JButton press

查看:35
本文介绍了在 JButton 按下时运行函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm attempting to make a program in java that uses a robot to press a specific key every few seconds. It has a GUI with a start and stop button and a label which tells which state its in. I've got everything working so far except that when I click "start" it runs the loop for my robot function (which is infinite) it doesn't enable the stop button like I thought it would. I know its something stupid with where the infinite loop is placed but I'm not sure how to make it work correctly.

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

I don't do a lot of java work, this was just a fun thing I thought to try but got stuck part way through. Any help is appreciated.

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++;

    }

}

推荐答案

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

I've adapted my comment into an answer.

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

The actionPerformed method of those event listeners are invoked on Swing's event dispatch thread, and since you're entering into an infinite loop, it'll cause the GUI to freeze. You could create a thread inside of your actionPerformed method and do your work inside of the new thread. Though the next issue you'd run into is finding a nice way to stop the thread whenever the user presses the stop button.

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

What's cool is that you've already got all the logic to do this in your code. So getting it to work is as simple as changing:

    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);
            }

        }
    });

在自己的线程上完成您的工作:

To do your work on its own thread:

    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(在这种情况下应该没问题).

The code above makes use of the executors framework (java.util.concurrent.*) rather than directly creating a thread. Another alternative as nachokk suggested would be to use a timer java.util.Timer or javax.swing.Timer (either should be fine in this case).

这篇关于在 JButton 按下时运行函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆