1

ボタンをクリックすると、特定の期間、パネルにランダムな色が表示される Java アプリケーションを作成しようとしています。

しかし、私の問題は、ボタンをクリックした後、フレームの色が一度だけ変化し、ボタンのタイトルが「U Clicked me」に変化しないことです。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

class MyDrawPanel extends JPanel {

    @Override
    public void paintComponent(Graphics g) {
        // g.fillRect(0, 0, this.getWidth(), this.getHeight())
        int red = (int) (Math.random() * 255);
        int green = (int) (Math.random() * 255);
        int blue = (int) (Math.random() * 255);
        Color randomizecolor = new Color(red, green, blue);
        g.setColor(randomizecolor);
        g.fillRect(0, 0, this.getWidth(), this.getHeight());
    }
}

public class CustomWidget implements ActionListener {

    JButton button;
    JFrame frame;

    public void Gui() {
        frame = new JFrame();
        MyDrawPanel pan = new MyDrawPanel();
        button = new JButton("-- Click Me to Change Me --");
        frame.add(BorderLayout.SOUTH, button);
        frame.add(BorderLayout.CENTER, pan);
        button.addActionListener(this);
        frame.setSize(500, 500);
        frame.setTitle("Random Color GUI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public void asd() {
        button.setText("U clicked Me");
        for (int i = 0; i < 150; i++) {
            frame.repaint();
            try {
                Thread.sleep(10);
            } catch (Exception x) {
            }
        }
        button.setText("Again Click me");
    }

    public static void main(String[] args) {
        CustomWidget obj = new CustomWidget();
        obj.Gui();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        this.asd();
        // this.button.setText("-- Click Me to Change Me --");
    }
}
4

1 に答える 1

4

Swing イベント スレッドを呼び出さないでくださいThread.sleep(...)。ペイント機能を含む GUI 全体がスリープ状態になるだけです。代わりにSwing Timerを使用してください。チュートリアルのリンクを確認してください。ちなみに、10 ミリ秒は非常に短く、タイム スライスや人々が気付くには短すぎる場合があります。また、paintComponent(...)メソッド自体ではなく、Swing Timer の ActionListener で新しい Color をランダム化して作成します。

編集:
Swing は単一のスレッド、イベント ディスパッチ スレッドまたは EDT を使用して、すべてのグラフィックを更新し、すべてのユーザー操作を行うことに注意してください。このスレッドをThread.sleep(...)呼び出して、またはこのスレッドで実行時間の長いコードを呼び出して、このスレッドをスリープ状態にすると、Swing アプリケーション全体がスリープ状態になり、スリープが終了するまでユーザーの操作や Swing の描画は行われません。解決の鍵は、長時間実行されるすべてのタスクをバックグラウンド スレッドで実行することです。Swing Timer がこれを行います。チュートリアルでその方法を説明します。

編集 2:
半疑似コード:

  button.setText(BTN_CLICKED_TEXT);
  // TIMER_DELAY is some constant int
  Timer myTimer = new Timer(TIMER_DELAY, new ActionListener() {
     private int count = 0;

     @Override
     public void actionPerformed(ActionEvent timerActionEvt) {
        if the count variable is >= some maximum count
          // stop the timer by calling stop on it
          // I'll show you this one since it is a bit complex
          ((Timer)timerActionEvt.getSource()).stop();
          // set the button text to its original state
          // return from this method

        else 
          // randomize pan's color and repaint it
          count++; // increment the counter variable
     }
  });

  myTimer.start();

タイマーがそれにアクセスできるようにするには、 pan 変数をそのコンストラクターではなく、Gui クラスで宣言する必要があることに注意してください。

于 2013-02-03T18:47:12.280 に答える