0

ループが終了すると、すべてのボタンとテキストフィールドが使用可能になりますが、ループの実行中は何もクリックできません。私はさまざまなことを試し、さまざまなサイトを見ましたが、何も役に立ちません。何が悪いのかわかりません!

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?
4

5 に答える 5

7

イベント ディスパッチ スレッド (GUI の描画とユーザー入力を処理するスレッド) でループしています。すべてのアクション イベントはそのスレッドで処理されます。長時間実行されるタスク (および I/O などの他のブロック操作) を実行する必要がある場合は、それらのタスクをワーカー スレッドにオフロードすることを検討する必要があります。詳細については、このチュートリアルをご覧ください。

于 2012-07-24T05:07:42.410 に答える
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;
    }

}

}

于 2012-07-24T05:18:30.923 に答える
1

これは、GUI を実行して 1 つのスレッドでループするためです。メソッド actionPerformed() に 1 つのブレーク ポイントを設定できます。他のイベントを受け入れることができない while ピースがまだ実行されていることがわかります。

于 2012-07-24T06:15:13.090 に答える
1

既に指摘したように、長時間実行されるすべてのタスクは、イベント ディスパッチ ループのスレッドとは別のスレッドで実行する必要があります。一方、GUI 要素とのすべての対話は、イベント ディスパッチ スレッドで発生する必要があります。

Dangling Piyush の例では、 Robot を呼び出しますWorkerThreadrobott()この場合、ロボット呼び出しは「安全」です。

ただし、Swing GUI 要素との直接的なやり取りがあった場合は、それらのやり取りをイベント ディスパッチ ループのスレッドに再ルーティングする必要があります。

方法 A: /SwingWorkerを持ってい ます。GUI を更新するコードでオーバーライドします。の実装から呼び出します。これは、イベント ディスパッチ ループ (そのスレッド上) から呼び出されるように「スケジュール」します。これにより、その境界を越えてパラメーターとしてデータを移動することが容易になります。publishprocessprocesspublishdoInBackgroundprocess

方法 B:SwingUtilities.invokeLater(Runnable doRun)定義した Runnable を使用して呼び出し、GUI 要素を更新します。そのランナブルは、目的のスレッドで実行されます。

于 2012-07-24T05:49:42.313 に答える
0

while ループは別のスレッドで実行する必要があります。同じ GUI スレッドで while ループを実行しているため、ボタンを押すことはできません。スイング コンポーネントはスレッド セーフではないことに注意してください。すべてのコンポーネントで後で呼び出しを使用してください。

于 2012-07-24T05:09:28.513 に答える