SwingWorker,Thread.sleep()或javax.swing.timer? 我需要“插入一个暂停”

我正在做一个记忆游戏,我想设置它,所以我点击第一个"card" ,然后第二个,如果他们不是相同的第二个卡显示几秒钟,然后他们回到"non-flipped"位置。

我尝试使用SwingWorkerThread.sleepSwingTimer但我不能让它工作。 使用Thread.sleep ,第二张牌不会"flip"如果它是重复的,它将等待睡眠时间并消失。 如果它不匹配,则等待“正面朝下”,在睡眠计时器之后,第一张卡片会翻转。 无论我在哪里放置Thread.sleep,都会发生这种情况。

随着Swing Timer只看起来“改变定时器”,而我正在与卡交互,所以我最终翻动8张卡之前,激活。

我没有与SwingWorker运气,我甚至不知道它会为我所寻找的。

这是我有的代码:

  class ButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { for(int index = 0; index < arraySize; index++) { if(button[index] == e.getSource()) { button[index].setText(String.valueOf(cards.get(index))); button[index].setEnabled(false); number[counter]=cards.get(index); if (counter == 0) { counter++; } else if (counter == 1) { if (number[0] == number[1]) { for(int i = 0; i < arraySize; i++) { if(!button[i].isEnabled()) { button[i].setVisible(false); } } } else { for(int i = 0; i < arraySize; i++) { if(!button[i].isEnabled()) { button[i].setEnabled(true); button[i].setText("Card"); } } } counter = 0; } } } } } 

基本上我需要的是这个代码在计数器== 1时执行,而且卡不匹配:

  button[index].setText(String.valueOf(cards.get(index))); button[index].setEnabled(false); 

然后暂停,以便当时card is revealed ,最后重新开始将卡片放回其面朝下的位置。

这是我用Thread.sleep()试过的:

 class ButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { for(int index = 0; index < arraySize; index++) { if(button[index] == e.getSource()) { button[index].setText(String.valueOf(cards.get(index))); button[index].setEnabled(false); number[counter]=cards.get(index); if (counter == 0) { counter++; } else if (counter == 1) { if (number[0] == number[1]) { for(int i = 0; i < arraySize; i++) { if(!button[i].isEnabled()) { button[i].setVisible(false); } } } else { try { Thread.sleep(800); } catch (InterruptedException e1) { e1.printStackTrace(); } for(int i = 0; i < arraySize; i++) { if(!button[i].isEnabled()) { button[i].setEnabled(true); button[i].setText("Card"); } } } counter = 0; } } } } } 

预先感谢您的任何build议

使用javax.swing.Timer来安排将来的事件触发。 这将允许您安全地更改UI,因为计时器是在事件派发线程的上下文中触发的。

能够同时翻转多张卡片的问题更多的是与你没有设置一个状态,防止用户翻转卡片,然后使用计时器。

下面的例子基本上每次只允许一张牌翻转。

一旦卡片在两个组中翻转,计时器启动。 当它被触发时,卡被重置。

在这里输入图像描述

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.LinearGradientPaint; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Random; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.LineBorder; public class FlipCards { public static void main(String[] args) { new FlipCards(); } public FlipCards() { 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 Card extends JPanel { private BufferedImage image; private boolean flipped = false; private Dimension prefSize; public Card(BufferedImage image, Dimension prefSize) { setBorder(new LineBorder(Color.DARK_GRAY)); this.image = image; this.prefSize = prefSize; } @Override public Dimension getPreferredSize() { return prefSize; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); LinearGradientPaint lgp = new LinearGradientPaint( new Point(0, 0), new Point(0, getHeight()), new float[]{0f, 1f}, new Color[]{Color.WHITE, Color.GRAY}); g2d.setPaint(lgp); g2d.fill(new Rectangle(0, 0, getWidth(), getHeight())); if (flipped && image != null) { int x = (getWidth() - image.getWidth()) / 2; int y = (getHeight() - image.getHeight()) / 2; g2d.drawImage(image, x, y, this); } g2d.dispose(); } public void setFlipped(boolean flipped) { this.flipped = flipped; repaint(); } } public class CardsPane extends JPanel { private Card flippedCard = null; public CardsPane(List<BufferedImage> images, Dimension prefSize) { setLayout(new GridBagLayout()); MouseAdapter mouseHandler = new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (flippedCard == null) { Card card = (Card) e.getComponent(); card.setFlipped(true); flippedCard = card; firePropertyChange("flippedCard", null, card); } } }; GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(4, 4, 4, 4); gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 0.25f; for (BufferedImage img : images) { Card card = new Card(img, prefSize); card.addMouseListener(mouseHandler); add(card, gbc); } } public Card getFlippedCard() { return flippedCard; } public void reset() { if (flippedCard != null) { flippedCard.setFlipped(false); flippedCard = null; } } } public class TestPane extends JPanel { private CardsPane topCards; private CardsPane bottomCards; private Timer resetTimer; public TestPane() { resetTimer = new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { topCards.reset(); bottomCards.reset(); } }); resetTimer.setRepeats(false); resetTimer.setCoalesce(true); PropertyChangeListener propertyChangeHandler = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { Card top = topCards.getFlippedCard(); Card bottom = bottomCards.getFlippedCard(); if (top != null && bottom != null) { resetTimer.start(); } } }; BufferedImage[] images = new BufferedImage[4]; try { images[0] = ImageIO.read(new File("./Card01.png")); images[1] = ImageIO.read(new File("./Card02.jpg")); images[2] = ImageIO.read(new File("./Card03.jpg")); images[3] = ImageIO.read(new File("./Card04.png")); Dimension prefSize = getMaxBounds(images); List<BufferedImage> topImages = new ArrayList<>(Arrays.asList(images)); Random rnd = new Random(System.currentTimeMillis()); int rotate = (int) Math.round((rnd.nextFloat() * 200) - 50); Collections.rotate(topImages, rotate); topCards = new CardsPane(topImages, prefSize); topCards.addPropertyChangeListener("flippedCard", propertyChangeHandler); List<BufferedImage> botImages = new ArrayList<>(Arrays.asList(images)); int botRotate = (int) Math.round((rnd.nextFloat() * 200) - 50); Collections.rotate(botImages, botRotate); bottomCards = new CardsPane(botImages, prefSize); bottomCards.addPropertyChangeListener("flippedCard", propertyChangeHandler); setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.insets = new Insets(4, 4, 4, 4); gbc.gridwidth = GridBagConstraints.REMAINDER; add(topCards, gbc); add(bottomCards, gbc); } catch (Exception e) { e.printStackTrace(); } } protected Dimension getMaxBounds(BufferedImage[] images) { int width = 0; int height = 0; for (BufferedImage img : images) { width = Math.max(width, img.getWidth()); height = Math.max(height, img.getHeight()); } return new Dimension(width, height); } } }