循环结束后,所有按钮和文本字段都可用,但循环运行时,无法单击任何按钮和文本字段。 我尝试了很多不同的东西,看了很多不同的网站,但没有什么可以帮助我。我无法找出问题所在!
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class J extends JFrame implements ActionListener{
JButton start = new JButton("Start (F12)");
JButton stop = new JButton("Stop");
int i;
JLabel delay = new JLabel("Delay: ");
JTextField delayJTF = new JTextField(4);
int delayS = 0;
GridLayout bl = new GridLayout(10, 10);
public J()
{
super("Auto Clicker");
start.addActionListener(this);
stop.addActionListener(this);
setSize(300, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(bl);
add(delay, BorderLayout.NORTH);
add(delayJTF, BorderLayout.NORTH);
add(start);
add(stop);
setVisible(true);
}
boolean run = false;
public static void main(String[] args) {
J j = new J();
}
public void robott() {
try {
Robot robot = new Robot();
Thread.sleep(delayS);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
// robot.delay(delayS);
} catch(Exception exc) {
System.out.println(exc);
}
}
public void actionPerformed(ActionEvent e) {
String delaySt = delayJTF.getText();
delayS = Integer.parseInt(delaySt);
System.out.println(delayS);
while(i < 100) {
i++;
robott();
System.out.println(i);
}
}
}
any suggestions?
答案 0 :(得分:7)
您正在循环事件调度线程 - 处理GUI绘制和用户输入的线程。所有操作事件都在该线程上处理。如果您需要执行长时间运行的任务(以及其他阻塞操作,如I / O),您应该考虑将这些任务卸载到工作线程。请查看this tutorial以获取更多信息。
答案 1 :(得分:1)
我已经修改了你的代码它现在正在运行.....你可以了解更多关于工作线程的信息
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class J extends JFrame implements ActionListener{
JButton start = new JButton("Start (F12)");
JButton stop = new JButton("Stop");
int i;
JLabel delay = new JLabel("Delay: ");
JTextField delayJTF = new JTextField(4);
int delayS = 0;
GridLayout bl = new GridLayout(10, 10);
public J()
{
super("Auto Clicker");
start.addActionListener(this);
stop.addActionListener(this);
setSize(300, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(bl);
add(delay, BorderLayout.NORTH);
add(delayJTF, BorderLayout.NORTH);
add(start);
add(stop);
setVisible(true);
}
boolean run = false;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
J j=new J();
}
});
}
public void robott() {
try {
Robot robot = new Robot();
Thread.sleep(delayS);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
} catch(Exception exc) {
System.out.println(exc);
}
}
public void actionPerformed(ActionEvent e) {
WorkerThread wt=new WorkerThread();
wt.execute();
}
class WorkerThread extends SwingWorker<Void , Void>{
@Override
protected Void doInBackground() throws Exception {
String delaySt = delayJTF.getText();
delayS = Integer.parseInt(delaySt);
System.out.println(delayS);
while(i < 100) {
i++;
robott();
System.out.println(i);
}
return null;
}
}
}
答案 2 :(得分:1)
正如已经指出的那样,所有长时间运行的任务必须在与Event Dispatch Loop的线程不同的线程上执行。另一方面,与GUI元素的所有交互必须发生在Event Dispatch Thread上。
在Dangling Piyush的例子中,WorkerThread
调用robott()
,称为机器人。在这种情况下,机器人呼叫是“安全的”。
但是,如果要与Swing GUI元素进行任何直接交互,则必须将这些交互重新路由回Event Dispatch Loop的Thread。
方法A:SwingWorker
有publish
/ process
。使用代码覆盖process
以更新GUI。从publish
的实现中调用doInBackground
,其中“调度”process
将从事件调度循环(在其线程上)调用。这有助于跨越该边界移动数据作为参数。
方法B:使用您定义的Runnable调用SwingUtilities.invokeLater(Runnable doRun)
以更新GUI元素。该runnable将在所需的线程上运行。
答案 3 :(得分:1)
这是因为您在一个线程中运行GUI并循环。您可以在方法actionPerformed()上设置一个断点。 它会被发现仍在运行不能接受任何其他事件的while片段。
答案 4 :(得分:0)
您应该在单独的线程中运行while循环。你不能按任何按钮,因为你在同一个GUI线程中运行while循环。请记住,swing组件不是线程安全的,所以稍后在所有组件中使用invoke。