1

setEnableボタンを時々設定するプログラムを作成しました。はThread.sleep()別のクラスにあります。コードは次のとおりです。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Try extends JFrame implements ActionListener{
JButton n1 = new JButton("1");
JButton n2 = new JButton("2");
JButton n3 = new JButton("3");
JButton show = new JButton("Show");

{
show.addActionListener(this);
n1.setEnabled(false);
n2.setEnabled(false);
n3.setEnabled(false);

}

public Try(){
  super("Try");
  setVisible(true);
  setSize(500, 200);
  setLayout(new GridLayout(1, 4));
  add(n1);
  add(n2);
  add(n3);
  add(show);
}  

public void actionPerformed(ActionEvent a) {
Object clicked = a.getSource();
if(show == clicked){
new EasyLevel1().start();
}
}

  class EasyLevel1 extends Thread {
    public void run() {      
        try {
            n1.setEnabled(true);
            Thread.sleep(1000);
            n1.setEnabled(false);
            n2.setEnabled(true);
            Thread.sleep(1000);
            n2.setEnabled(false);
            n3.setEnabled(true);
            Thread.sleep(1000);
            n3.setEnabled(false);    
        } catch (InterruptedException e){
        }
        }
      }

    public static void main(String[] args){
      Try frame = new Try();
      frame.setVisible(true);
    }
    }

ただし、actionListenerクラス内でそれを配置すると:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Try extends JFrame implements ActionListener{
JButton n1 = new JButton("1");
JButton n2 = new JButton("2");
JButton n3 = new JButton("3");
JButton show = new JButton("Show");

{
show.addActionListener(this);
n1.setEnabled(false);
n2.setEnabled(false);
n3.setEnabled(false);

}

public Try(){
  super("Try");
  setVisible(true);
  setSize(500, 200);
  setLayout(new GridLayout(1, 4));
  add(n1);
  add(n2);
  add(n3);
  add(show);
}  

public void actionPerformed(ActionEvent a) {
Object clicked = a.getSource();
if(show == clicked){
            try {n1.setEnabled(true);
            Thread.sleep(1000);
            n1.setEnabled(false);
            n2.setEnabled(true);
            Thread.sleep(1000);
            n2.setEnabled(false);
            n3.setEnabled(true);
            Thread.sleep(1000);
            n3.setEnabled(false);
            } catch (InterruptedException e){}
}
}

public static void main(String[] args){
  Try frame = new Try();
  frame.setVisible(true);
}
}

その例に基づいて、プログラム全体がフリーズします。現在のクラスがフリーズするのを防ぐには、別のスレッドでスレッドスリープを実行する必要があることを理解しました。しかし、新しい thread.sleep はまだ上記のコードを実行するように操作をフリーズしていると予想していましたが、ボタンは別のスレッドにあるため応答します。しかし、驚くべきことに、最初のプログラムのようにすべてを即座に無効にするわけではありませんでした。

4

3 に答える 3

3

Thread.sleep()現在のスレッドを一時停止します。actionPerformedSwing Event 内の で実行しています。すべての Swing 操作は、EDT という単一のスレッドで実行されます。Thread.sleep() で一時停止すると、actionPerformed リスナーから戻っていないため、Swing は他のイベントを処理できません。したがって、GUI がフリーズします (完全なアプリケーションではなく、GUI だけです)。

一般に、このため、Swing イベントで実行時間の長いアクションを実行することはお勧めできません。あなたがやろうとしていることに対して、良い代替手段は Swing タイマーを使用することです。

于 2013-03-24T01:25:07.007 に答える
2

Thread.sleep呼び出しを実行するスレッドを、指定された時間 (またはスレッドが中断されるまで) スリープ状態にします。メソッドで呼び出すとactionPerformed、UI スレッドがスリープ状態になります。そのため、プログラムがロックされています。

スリープ中に行うさまざまな呼び出しをステップ実行する別のスレッドを開始する必要があります。別の方法として (私の意見では、はるかに優れています)、Swing タイマーを使用して、必要なことを行うことができます。

于 2013-03-24T01:25:48.130 に答える
2

何が起こっているかというと、2 番目の例Thread.sleepでは がブロックされているEDTため、それ以上の UI 更新は発生しません。対照的に、最初の例sleepでは、separareを呼び出しているThreadため、「フリーズ」は発生しません。このようなタスクでは、スイング タイマーの使用が推奨されます。

于 2013-03-24T01:26:07.707 に答える