摆动计时器不能正常工作

嗨,我正在研究一个项目(Java记忆游戏),首先我想了解摇摆计时器是如何工作的。 首先,我的主类实现了ActionListenerItemListener 。 并且我在actionPerformed(ActionEvent e)使用计时器,如果用户选择不同图片的两张卡然后我使用timer.start()给他几秒钟看图片,然后他们将再次关闭。 但如果用户选择两张不同的图片,他们会突然关闭,所以我看不到第二张图片。 我读了一些关于摇摆计时器的教程,但我想我错误地理解了。通过我创建我的SSCCE的方式,如果你能帮助我,我将不胜感激。 谢谢anwyway …

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.GridLayout; import java.awt.Image; import java.awt.Menu; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.Random; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JToggleButton; import javax.swing.Timer; import javax.swing.UIManager; import javax.swing.border.*; public class ConcentrationGame4 extends JFrame implements ActionListener, ItemListener{ private static final long serialVersionUID = 1L; private int buttoncounter=0; private int counter = 0; private JFrame frame; private JPanel mainPanel; private JPanel buttonPanel; private JMenuBar menuBar; private JMenu menu; private JMenuItem menuItem; private int[] arr = new int[16]; private int i,j; private int random; private int size = 4; private Icon hidden; private GameButton buttonFirst; private GameButton buttonSecond; private Timer timer; private Icon img[] = {UIManager.getIcon("OptionPane.errorIcon"), UIManager.getIcon("OptionPane.informationIcon"), UIManager.getIcon("OptionPane.warningIcon")}; private Icon iconList[] = new ImageIcon[size]; public ConcentrationGame4(){ createArray(); initComponents(); } private void initComponents(){ frame = new JFrame("Concentration Game"); menuBar = new JMenuBar(); menu = new JMenu("Menu"); frame.setJMenuBar(menuBar); menuBar.add(menu); menuItem = new JMenuItem("New Game"); menu.add(menuItem); menuItem = new JMenuItem("Solve"); menu.add(menuItem); menuItem = new JMenuItem("Exit"); menu.add(menuItem); mainPanel = new JPanel(new BorderLayout(5, 5)); mainPanel.setBorder(new EmptyBorder(4,4,4,4)); frame.setContentPane(mainPanel); buttonPanel = new JPanel(new GridLayout(4,4,5,5)); buttonPanel.setBackground(Color.green); timer = new Timer(2000,this); for(i=0; i<4; i++){ final GameButton button = new GameButton(iconList[i]); button.addItemListener(this); button.addActionListener(this); buttonPanel.add(button); } mainPanel.add(buttonPanel, BorderLayout.CENTER); frame.setSize(300, 300); //frame.pack(); frame.setLocation(300, 300); frame.setVisible(true); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); } public void itemStateChanged(ItemEvent e){ GameButton button = (GameButton) e.getItem(); button.setState(); } public void actionPerformed(ActionEvent e){ GameButton button = (GameButton) e.getSource(); if(button.isSelected()){ buttoncounter++; if(buttoncounter==1){ buttonFirst = (GameButton) e.getSource(); } else if(buttoncounter==2){ buttonSecond = (GameButton) e.getSource(); buttoncounter=0; if( checkPairs(buttonFirst,buttonSecond) ) { retirePair(buttonFirst,buttonSecond); } else{ timer.start(); falsePair(buttonFirst, buttonSecond); } } } } class GameButton extends JToggleButton{ private static final long serialVersionUID = 1L; private Icon icon; public GameButton(Icon icon){ this.icon = icon; } public void setState() { if (this.isSelected() || !this.isEnabled()) { this.setIcon(icon); } else { this.setIcon(hidden); } } } private void retirePair(GameButton a, GameButton b){ a.setSelected(true); a.setEnabled(false); b.setSelected(true); b.setEnabled(false); } private void falsePair(GameButton buttonFirst, GameButton buttonSecond){ buttonFirst.setIcon(hidden); buttonFirst.setSelected(false); buttonSecond.setIcon(hidden); buttonSecond.setSelected(false); } private boolean checkPairs(GameButton first, GameButton second){ if(first.getIcon().equals(second.getIcon())) return true; else return false; } private void createArray(){ Random rnd = new Random(); while(i<4){ random = rnd.nextInt(3)+1; if(!includes(random)){ arr[i]=random; iconList[i] = img[random-1]; i++; } } } public boolean includes(int rnd){ counter=0; for(j=0; j1) return true; } } return false; } /** * @param args */ public static void main(String[] args) { new ConcentrationGame4(); } } 

使用Swing Timer暂停xxx秒动作的示例:

 import java.awt.*; import java.awt.event.*; import javax.swing.*; @SuppressWarnings("serial") public class QuickTimerEg extends JPanel { private static final int TIMER_DELAY = 2000; private boolean buttonsWorking = true; private JButton btn1 = null; private JButton btn2 = null; private Timer swingTimer; public QuickTimerEg() { ActionListener btnListener = new ActionListener() { public void actionPerformed(ActionEvent e) { btnActionPerformed(e); } }; setLayout(new GridLayout(4, 4)); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { JButton button = new JButton(" "); button.addActionListener(btnListener); add(button); } } } private void btnActionPerformed(ActionEvent e) { if (!buttonsWorking) { return; } JButton button = (JButton)e.getSource(); button.setBackground(Color.blue); button.setEnabled(false); if (btn1 == null) { btn1 = button; } else { buttonsWorking = false; btn2 = button; swingTimer = new Timer(TIMER_DELAY, new ActionListener() { public void actionPerformed(ActionEvent e) { btn1.setBackground(null); btn2.setBackground(null); btn1.setEnabled(true); btn2.setEnabled(true); btn1 = null; btn2 = null; buttonsWorking = true; } }); swingTimer.setRepeats(false); swingTimer.start(); } } private static void createAndShowGui() { JFrame frame = new JFrame("QuickTimerEg"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new QuickTimerEg()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } 

我不知道你想做什么,但是你将this作为参数传递给Timer构造函数。 这意味着每2秒,将调用this actionPerformed方法(ConcentrationGame4的实例)。 这种方法的第一件事就是

 GameButton button = (GameButton) e.getSource(); 

显然,这将抛出exception,因为事件的起源不是游戏按钮,而是计时器。

要了解Timer的function及其工作原理,它非常简单。 您只需阅读其API文档: http : //download.oracle.com/javase/6/docs/api/javax/swing/Timer.html 。 本文档甚至可以通过示例向您介绍解释它们如何工作的教程。

另外,您可能希望使用ListList 。 这种Collections很容易以可靠的方式洗牌。 另外,请注意GameButton类外部的单个GameButton与它们的集合之间的区别。 这是您点击任何一个按钮时需要检查的集合

 import java.awt.EventQueue; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JToggleButton; import javax.swing.Timer; import javax.swing.UIManager; /** @see http://stackoverflow.com/questions/7933424 */ public class ButtonTimer extends JPanel { private List list = new ArrayList(); private List buttons = new ArrayList(); private Timer timer = new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { createPanel(); } }); public ButtonTimer() { this.setLayout(new GridLayout(1, 0)); list.add(UIManager.getIcon("OptionPane.errorIcon")); list.add(UIManager.getIcon("OptionPane.informationIcon")); list.add(UIManager.getIcon("OptionPane.warningIcon")); list.add(UIManager.getIcon("OptionPane.questionIcon")); createPanel(); timer.start(); } private void createPanel() { Collections.shuffle(list); this.removeAll(); for (Icon icon : list) { GameButton gb = new GameButton(icon); buttons.add(gb); this.add(gb); } this.revalidate(); } class GameButton extends JToggleButton { private Icon icon; public GameButton(Icon icon) { super(icon); this.icon = icon; } } private void display() { JFrame f = new JFrame("ButtonTimer"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(this); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new ButtonTimer().display(); } }); } }