更改线程中的JButton颜色

我正在尝试制作像西蒙这样的游戏: http ://www.freegames.ws/games/kidsgames/simon/simon.htm#

我只用2个按钮缩小比例。 我希望颜色在2个按钮,button1和button2之间切换。 这是一个线程,因为我需要在发生这种情况时点击按钮。 当我打开程序时,按钮颜色保持原样。

提前感谢您的帮助!

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的单线程要求。 必须在Event Dispatching Thread的上下文中对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中的Concurrency

 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属性。