这就是用Java中的autoclicker和GUI处理多线程的方式吗?
我希望通过Robot类在Java中创建一个带有JFrame GUI的自动clicker。我想知道这是否是在不同线程中创建GUI的最佳方法,这样即使在自动舔板器/机器人执行操作时也能保持响应 我在Oracle文档中读到Swing对象有自己的事件调度程序线程,所以可能根本不需要这样做?如果是,是什么?提前谢谢这就是用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
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自学成才的程序员。然而,如果听者能够区分机器人点击和实际用户点击(例如,当机器人调用鼠标单击方法时,让某个变量更新侦听器)我很想听到!