我正在尝试使用Swing(Jframe / jbuttons /网格设置)进行补救。目前我无法弄清楚如何让一系列按钮闪烁。由于actionPerformed
非静态,我无法通过我的摇摆计时器运行一个线程。我不知道该怎么做。
如果有人能看一眼我的代码并提供见解,我真的很感激。
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){}
}
}
}
}
答案 0 :(得分:3)
您可以创建自己的线程(或者更确切地说是Runnable)来闪烁按钮并在呼叫之间休眠,例如
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类的目的。
答案 1 :(得分:3)
正如@Cameron Skinner所建议的,这个example使用javax.swing.Timer
来为一个简单的匹配游戏闪烁按钮。 Timer
特别方便,因为它的动作事件处理程序在事件派发线程上执行。