这就是用Java中的autoclicker和GUI处理多线程的方式吗?

这就是用Java中的autoclicker和GUI处理多线程的方式吗?,java,multithreading,swing,user-interface,Java,Multithreading,Swing,User Interface,我希望通过Robot类在Java中创建一个带有JFrame GUI的自动clicker。我想知道这是否是在不同线程中创建GUI的最佳方法,这样即使在自动舔板器/机器人执行操作时也能保持响应 我在Oracle文档中读到Swing对象有自己的事件调度程序线程,所以可能根本不需要这样做?如果是,是什么?提前谢谢 package Engine; import javax.swing.*; import GUI.UI; public class Engine { private Thread

我希望通过Robot类在Java中创建一个带有JFrame GUI的自动clicker。我想知道这是否是在不同线程中创建GUI的最佳方法,这样即使在自动舔板器/机器人执行操作时也能保持响应

我在Oracle文档中读到Swing对象有自己的事件调度程序线程,所以可能根本不需要这样做?如果是,是什么?提前谢谢

package Engine;
import javax.swing.*;
import GUI.UI;

public class Engine {

    private Thread UIthread, clickerThread;
    public UI ui;
    public AutoClicker autoClicker;

    public Engine(int width, int height) {

        ui = new UI(width, height);
        ui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ui.setVisible(true);

        UIthread = new Thread(ui);
        UIthread.start();

        //autoclicker is where the Robot class 
        autoClicker = new AutoClicker();
        clickerThread = new Thread(autoClicker);
        clickerThread.start();
    }



}
以下是UI(及其事件处理程序)和AutoClicker类,以防它们有所帮助:

package GUI;

import javax.swing.*;

public class UI extends JFrame implements Runnable{

    public int width, height;
    JButton start, stop;


    public UI(int width, int height) {
        this.width = width;
        this.height = height;
        this.setLayout(null);
        this.setSize(width, height);
    }

    public void init() {
        start = new JButton();
        start.setText("start");
        start.setBounds(100, 100, 100, 30);
        add(start);

        stop = new JButton();
        stop.setText("stop");
        stop.setBounds(100, 140, 100, 30);
        add(stop);

        EventHandler eHandler = new EventHandler(this);
        start.addActionListener(eHandler);
        stop.addActionListener(eHandler);
    }

    @Override
    public void run() {
        init();

    }
}
EventHandler类

    package GUI;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    public class EventHandler implements ActionListener{

        private UI ui;

        public EventHandler(UI ui) {
            this.ui = ui;
        }

        public void actionPerformed(ActionEvent actionEvent) {
            if(actionEvent.getSource().equals(ui.start)) {
                //start autoclicking
                System.out.println("start");
            }else if(actionEvent.getSource().equals(ui.stop)) {
                //stop autoclicking 
                System.out.println("stop");
            }

        }

    }
自动单击器类:

package Engine;

import java.awt.AWTException;
import java.awt.Robot;

public class AutoClicker implements Runnable{

    private Robot robot;

    public void run() {

        try {
            robot = new Robot();
            //do mouse clicks and stuff 

        } catch (AWTException e) {
            e.printStackTrace();
        }


    }

}

您正在讨论的事件调度线程实际上就是您应该与
javax.swing
一起使用以创建响应GUI的线程。当您要显示窗口时,应该通过
javax.swing.SwingUtilites
类为EDT安排一个作业。例如:

import javax.swing.*;

public class HelloWorldSwing {
    private static void createAndShowGUI() {
        // Create and set up the window.
        JFrame frame = new JFrame("HelloWorldSwing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Add the ubiquitous "Hello World" label.
        JLabel label = new JLabel("Hello World");
        frame.getContentPane().add(label);

        // Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        // Schedule a job for the event-dispatching thread:
        // creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
(代码直接取自)

这里最重要的部分是
main
方法:它确保其他代码可以自由使用主线程,并且GUI不会在下载大文件时没有响应(然后,根据情况,它也应该在自己的线程中)

现在,如果我们将您提供的代码放入
Main
类中:

import Engine.*;

public class Main {
    public static void main(String[] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Engine(640, 400);
            }
        });
    }
}
有了所有这些,GUI现在在一个单独的线程中运行,但是在
引擎
类中创建了两个新线程,从而在某种程度上导致EDT有两个子线程。您应该消除UI的线程;它真正做的只是在一个单独的线程中向原始窗口添加额外的组件,这在您考虑它时有点过头了


现在,关于自动舔舐机。您应该实现这一点,这样当按下“开始”按钮时,一个新线程将生成一个
Runnable
,只要某个布尔值为true,它就会循环,并以您想要的速度单击。按下“停止”按钮时(我猜机器人仍处于活动状态…),将该布尔值设置为false。这应该都在
EventHandler.actionPerformed
方法中。

This.setLayout(null)1)Java GUI必须在不同的操作系统、屏幕大小、屏幕分辨率等上工作,在不同的地区使用不同的PLAF。因此,它们不利于像素完美布局。而是使用布局管理器,或与布局填充和边框一起使用。2) 为了更快地获得更好的帮助,请发布一个or。
我想知道这是否是在不同线程中创建GUI的最佳方法,以便在自动单击器/机器人执行操作时仍能保持响应?
-您认为这将如何工作?如果用户正忙着在框架上做一些事情,而机器人做了一些事情,那么当这两个功能同时完成时会发生什么呢。作为一个用户,我会非常沮丧地将鼠标移动到一个组件上,却让机器人将鼠标移动到另一个组件上。设计响应GUI的要点是让代码在侦听器代码中高效执行。侦听器代码不知道用户或机器人是否单击了按钮。因此,机器人在单独的线程中执行并不是真正的问题。任何长时间运行的侦听器代码都需要在单独的线程中执行。有关详细信息,请阅读上Swing教程的部分。@camickr感谢您的评论!这不是真的供消费者使用,也不是供学校使用,它只是供我个人使用,所以我可以容忍某种预兆,让机器人睡眠一段时间,让我有机会按下停止按钮。我的主要问题其实只是“如何”多线程处理GUI和另一个对象,因为我是一个真正的新手和youtube自学成才的程序员。然而,如果听者能够区分机器人点击和实际用户点击(例如,当机器人调用鼠标单击方法时,让某个变量更新侦听器)我很想听到!