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

不要调用Thread.sleep(...)Swing 事件线程,因为所有这些都会使整个 GUI 进入睡眠状态,包括它的绘画能力。而是使用Swing Timer。检查教程的链接。顺便说一句,10 毫秒非常短,对于时间片或人们来说可能太短了。另外,我会在 Swing Timer 的 ActionListener 中而不是在paintComponent(...)方法本身中随机化并创建新的颜色。

编辑:
请注意,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();

请注意,必须在 Gui 类中声明 pan 变量,而不是在其构造函数中声明,以便 Timer 能够访问它。

于 2013-02-03T18:47:12.280 回答