Java 按钮在两种背景色之间闪烁
我的问题:在我的场景中,程序延迟的有效方式 我的场景: 我正在为一个简短的项目做一个问答游戏,长话短说。当用户按下四个有答案的按钮中的一个时,就会回答问题。然后我的quizengine类调用此处显示的paintbutton方法。在这之后,它继续调用其他一些方法,以使下一个问题出现。现在我想让按钮在两种颜色之间切换,时间间隔越短越好 到目前为止我尝试了什么: 首先,我在paintbutton方法和将界面更改为下一个问题的方法之间放置了一个JoptionPane,以查看按钮是否会更改颜色。它成功地做到了。当然那不是我的本意,我只想要一个时间间隔。 然后我试着用Thread.Sleep。虽然程序会在更改为下一个问题之前等待,但颜色变化不可见。 最后,我尝试了一个计时器的实现(可能不正确),虽然它改变了颜色,但程序继续进行并继续下一个问题 我想成为代码Java 按钮在两种背景色之间闪烁,java,swing,animation,time,intervals,Java,Swing,Animation,Time,Intervals,我的问题:在我的场景中,程序延迟的有效方式 我的场景: 我正在为一个简短的项目做一个问答游戏,长话短说。当用户按下四个有答案的按钮中的一个时,就会回答问题。然后我的quizengine类调用此处显示的paintbutton方法。在这之后,它继续调用其他一些方法,以使下一个问题出现。现在我想让按钮在两种颜色之间切换,时间间隔越短越好 到目前为止我尝试了什么: 首先,我在paintbutton方法和将界面更改为下一个问题的方法之间放置了一个JoptionPane,以查看按钮是否会更改颜色。它成功地做
/* Paints the button pressed red or green
* Green if the anwser is correct red if
* its false
*
* @param int bnr the number of the button
* @param boolean corr true if correct false if false :D
*/
public static void paintbutton(int bnr,boolean corr) {
for (int i=10;i>1;i--){
b[bnr-1].setBackground(null);
//wait for i*100 milliseconds
b[bnr-1].setBackground(corr?Color.green:Color.red);
}
}
让我们从一些基本知识开始。Swing是单线程的,这意味着您决不能在事件调度线程的上下文中阻止或执行长时间运行的代码,这将使UI冻结,用户感到不安 Swing不是线程安全的,这意味着您永远不应该在EDT上下文之外创建或更新UI 这会让你陷入一个问题。您希望在稍微延迟之后更新UI 幸运的是,至少有两种可能性,一种是Swing
定时器
或一种是SwingWorker
Swing计时器相对简单,但并不能真正提供在更新之间生成可变延迟的方法。SwingWorker
更为复杂,但它可以让您控制基本上做您想做的事情
这两者都可以在EDT之外“等待”,但都提供了安全地将更新推送到EDT的方法
例如
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.GridBagLayout;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.beans.PropertyChangeEvent;
导入java.beans.PropertyChangeListener;
导入java.util.List;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.SwingWorker;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公共类闪烁按钮{
公共静态void main(字符串[]args){
新的闪烁按钮();
}
公共闪烁按钮(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展了JPanel{
私人杰布顿·布林基;
公共测试窗格(){
blinky=新的JButton(“blinky”);
blinky.set不透明(true);
addActionListener(新ActionListener()){
私人工人;
@凌驾
已执行的公共无效操作(操作事件e){
if(worker==null | | worker.getState()==SwingWorker.StateValue.DONE){
worker=新的BlinkWorker(blinky,Color.RED);
worker.addPropertyChangeListener(新的PropertyChangeListener(){
@凌驾
公共作废属性更改(属性更改事件evt){
SwingWorker worker=(SwingWorker)evt.getSource();
if(“state”.equals(evt.getPropertyName())){
if(worker.getState()==SwingWorker.StateValue.DONE){
//在这里,您将调用该方法
//更新新问题的状态
}
}
}
});
worker.execute();
}
}
});
setLayout(新的GridBagLayout());
添加(闪烁);
}
@凌驾
公共维度getPreferredSize(){
返回新维度(200200);
}
公共类BlinkWorker扩展SwingWorker{
专用按钮btn;
私人色彩;
私人色彩正常;
公共眨眼工人(JButton btn,彩色){
this.btn=btn;
normal=btn.getBackground();
这个颜色=颜色;
}
@凌驾
受保护的Void doInBackground()引发异常{
对于(int-index=10;index>1;index--){
出版(彩色);
睡眠(指数*100);
发布(正常);
睡眠(指数*100);
}
返回null;
}
@凌驾
受保护的无效进程(列表块){
颜色=块。获取(块)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class BlinkyTheButton {
public static void main(String[] args) {
new BlinkyTheButton();
}
public BlinkyTheButton() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JButton blinky;
public TestPane() {
blinky = new JButton("Blinky");
blinky.setOpaque(true);
blinky.addActionListener(new ActionListener() {
private BlinkWorker worker;
@Override
public void actionPerformed(ActionEvent e) {
if (worker == null || worker.getState() == SwingWorker.StateValue.DONE) {
worker = new BlinkWorker(blinky, Color.RED);
worker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
SwingWorker worker = (SwingWorker) evt.getSource();
if ("state".equals(evt.getPropertyName())) {
if (worker.getState() == SwingWorker.StateValue.DONE) {
// this is where you would then call the method to
// update the state for a new question
}
}
}
});
worker.execute();
}
}
});
setLayout(new GridBagLayout());
add(blinky);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
public class BlinkWorker extends SwingWorker<Void, Color> {
private JButton btn;
private Color color;
private Color normal;
public BlinkWorker(JButton btn, Color color) {
this.btn = btn;
normal = btn.getBackground();
this.color = color;
}
@Override
protected Void doInBackground() throws Exception {
for (int index = 10; index > 1; index--) {
publish(color);
Thread.sleep(index * 100);
publish(normal);
Thread.sleep(index * 100);
}
return null;
}
@Override
protected void process(List<Color> chunks) {
Color color = chunks.get(chunks.size() - 1);
btn.setBackground(color);
}
}
}
}
public static void paintbutton(int bnr,boolean corr) {
long time;
try {
Robot robot = new Robot();
for (int i=5;i>1;i--){
b[bnr-1].setBackground(null);
// Simulate a key press
robot.keyPress(KeyEvent.VK_SPACE);
robot.keyRelease(KeyEvent.VK_SPACE);
JOptionPane.showMessageDialog(null,"hi");
time = System.currentTimeMillis();
do {
}while(time+i*100>System.currentTimeMillis());
b[bnr-1].setBackground(i==1?(corr?Color.green:Color.red):Color.yellow);
// Simulate a key press
robot.keyPress(KeyEvent.VK_SPACE);
robot.keyRelease(KeyEvent.VK_SPACE);
JOptionPane.showMessageDialog(null,"hi");
time = System.currentTimeMillis();
do {
}while(time+i*100>System.currentTimeMillis());
}
} catch (AWTException e) {
System.err.println("error");
}
}