更改线程中的JButton颜色



我正试图制作一款类似simon的游戏:http://www.freegames.ws/games/kidsgames/simon/simon.htm#

我正在做一个只有两个按钮的小比例尺。我想让颜色在两个按钮之间切换,按钮1和按钮2。这是在一个线程中,因为我需要在发生这种情况时单击按钮。当我打开程序时,按钮的颜色保持原样。

感谢您的提前帮助!

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.*;
public class TestFrame extends JFrame{
    public JButton button1; 
    public JButton button2;
    boolean isTrue = true;
    boolean switchColor = true;
    TestFrame(){
        super("Simon");
        initialize();
        this.setSize(200, 400);
        this.setVisible(true);
    }
    private void initialize() {
         this.setLayout(new BorderLayout()); 
        button1 = new JButton();
        button1.setBackground(Color.green);
        button1.setSize(200,200);
        button2 = new JButton();
        button2.setSize(200, 200);
        button2.setBackground(Color.blue);
        this.add(button1, BorderLayout.NORTH);
        this.add(button2, BorderLayout.SOUTH);
        Thread t = new Thread(r1);
        t.start();
    }
    Runnable r1 = new Runnable() {
        public void run() {
            while(isTrue){
            if(switchColor = true){
                button1.setBackground(Color.blue);
                button2.setBackground(Color.green);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                refresh();
                switchColor = false;
            } else {
                button1.setBackground(Color.green);
                button2.setBackground(Color.blue);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                refresh();
                switchColor = true;
                }
            }
        }
    };
    public void refresh(){
        this.invalidate();
        this.validate();
        this.repaint();
    }
}

有很多问题很突出(shazin已经解决了其中一个),另一个让我害怕的是你违反了Swing的单线程要求。对UI的所有更改都必须在事件调度线程的上下文中进行。

您应该使用javax.swing.Timer,而不是使用Thread。这将使您无需将更新重新同步回EDT。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FlashyButtons {
    public static void main(String[] args) {
        new FlashyButtons();
    }
    public FlashyButtons() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }
                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
    public class TestPane extends JPanel {
        private JButton btn1;
        private JButton btn2;
        private int count = 0;
        public TestPane() {
            setLayout(new GridBagLayout());
            btn1 = new FlashButton();
            btn2 = new FlashButton();
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            add(btn1, gbc);
            add(btn2, gbc);
            btn1.setBackground(Color.GREEN);
            btn2.setBackground(Color.BLUE);
            Timer timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    count++;
                    if (count % 2 == 0) {
                        btn1.setBackground(Color.BLUE);
                        btn2.setBackground(Color.GREEN);
                    } else {
                        btn1.setBackground(Color.GREEN);
                        btn2.setBackground(Color.BLUE);
                    }
                }
            });
            timer.start();
        }
    }
    public class FlashButton extends JButton {
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
    }
}

查看Swing中的并发以了解更多详细信息

if(switchColor = true){
    button1.setBackground(Color.blue);
    button2.setBackground(Color.green);
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    refresh();
    switchColor = false;
} else {
    button1.setBackground(Color.green);
    button2.setBackground(Color.blue);
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    refresh();
    switchColor = true;
    }
}

在上述代码中,将以下内容更改为

if(switchColor = true){

if(switchColor == true){ 

或者只是

if(switchColor){

最好让你的Runnable匿名类在中

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    }
});

而不是使用新的Thread对象来创建和启动线程,因为它将更改Swing UI属性。

最新更新