我正在尝试创建一个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 --");
}
}
答案 0 :(得分:4)
不要在Swing事件线程上调用Thread.sleep(...)
,因为所有这一切都会使整个GUI处于休眠状态,包括它的绘制能力。而是使用Swing Timer。查看教程的链接。顺便提一下,10毫秒非常短,可能对于时间片太短或者人们没有注意到。另外,我会在Swing Timer的ActionListener中随机化并创建新的Color,而不是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();
请注意,pan变量必须在Gui类中声明,而不是在其构造函数中声明,以便Timer能够访问它。