Java Swing闪烁按钮序列

我正在尝试使用Swing(Jframe / jbuttons / grid setup)进行补救。 目前我无法弄清楚如何让一系列按钮闪烁。 因为actionPerformed是非静态的,所以我无法通过我的swing计时器运行一个线程。 我不知道该怎么办。

如果有人能看一眼我的代码并提供见解,我真的很感激。

 package MemoryGame; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.*; import java.awt.event.*; import java.awt.*; import java.util.Random; import java.lang.InterruptedException; public class GUI { static int seconds = 0; static int buttonIndex = 0; int[] movesArr = new int[10]; int numberOfButtons = 18; Thread thread = new Thread(); boolean[] logicArr = new boolean[numberOfButtons]; JFrame frame = new JFrame("Memory Builder"); JPanel buttonPanel = new JPanel(); JPanel panelBot = new JPanel(new BorderLayout()); GridLayout grid = new GridLayout(0, 3) {{ setHgap(8); setVgap(8); }}; JLabel scoreLabel = new JLabel("Score"); static JLabel timeLabel = new JLabel("0"); JButton button[] = new JButton[numberOfButtons]; Listener listener = new Listener(); Timer displayTimer = new Timer(1000, listener.new DisplayTimeListener()); Timer buttonTimer = new Timer(300, listener.new ButtonDisplayListener()); Color buttonColor; public GUI() { //Setup frame frame.setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create button panel buttonPanel.setLayout(grid); buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); addButtonPanel(); //create label pane panelBot.add(timeLabel, BorderLayout.WEST); panelBot.add(scoreLabel, BorderLayout.EAST); } public void centerFrame() { Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); frame.setLocation((dim.width - frame.getWidth()) / 2, (dim.height - frame.getHeight()) / 2); } public void addButtonPanel() { for (int i=0; i < button.length; i++){ button[i] = new JButton(); button[i].addActionListener(listener.new ButtonListener()); button[i].setText("Button " + (i + 1)); button[i].setName(new Integer(i).toString()); buttonPanel.add(button[i]); } buttonColor = button[0].getBackground(); } public void createGUI() { frame.add(buttonPanel); frame.add(new JSeparator()); frame.add(panelBot); frame.pack(); centerFrame(); buttonPanel.setVisible(true); frame.setVisible(true); displayTimer.start(); runGame(); } public void runGame() { boolean isGameOver = false; int difficulty = 3; Random random = new Random(); //generate and display random sequence for(int i = 0; i < difficulty; i++) { movesArr[i] = random.nextInt(numberOfButtons); System.out.println(movesArr[i]); } new BlinkThread().run(); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable(){ public void run(){ new GUI().createGUI(); } }); } public class Listener { boolean flag = true; public class ButtonDisplayListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (flag){ button[buttonIndex].setBackground(Color.red); flag = !flag; } else button[buttonIndex].setBackground(buttonColor); } } public class DisplayTimeListener implements ActionListener { public void actionPerformed(ActionEvent e) { GUI.timeLabel.setText(new Integer(seconds++).toString()); } } public class ButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { } } } class BlinkThread implements Runnable { public void run(){ for(int i: movesArr){ try{ Thread.sleep(200); System.out.println("echo"); button[i].setBackground(Color.RED); Thread.sleep(200); button[i].setBackground(buttonColor); } catch(Exception ex){} } } } } 

您可以创建自己的线程(或者更确切地说,一个Runnable)来闪烁按钮并在呼叫之间hibernate,例如

 class FlashThread implements Runnable { private int[] indices; private int sleepTime; ... suitable constructor public void run() { for (int i : indices) { buttonOn(i); Thread.sleep(sleepTime); buttonOff(i); Thread.sleep(sleepTime); } } } 

这应该够了吧。

或者,您可以创建一个计时器并向其添加一个ActionListener(类似于您使用ButtonDisplayListener执行的操作)等。

顺便说一句,每次通过runGame()循环时都不要创建一个新的Random对象。 生成一次(最好是作为实例变量而不是本地变量)然后多次使用它。 随机对象生成(可能)很昂贵,并且生成一堆Random对象有点违背了Random类的目的。

正如@Cameron Skinner所建议的那样,这个例子使用javax.swing.Timer为一个简单的匹配游戏闪烁按钮。 Timer特别方便,因为它的动作事件处理程序在事件派发线程上执行。