SwingWorker,Thread.sleep()或javax.swing.timer?我需要“插入暂停”。 [英] SwingWorker, Thread.sleep(), or javax.swing.timer? I need to "insert a pause"

查看:95
本文介绍了SwingWorker,Thread.sleep()或javax.swing.timer?我需要“插入暂停”。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一款记忆游戏,我想设置它,所以我点击第一张卡片,然后是第二张,如果它们不一样的话第二张卡显示几秒钟,然后他们返回非翻转位置。

I'm working on a memory game and I want to set it up so I click the first "card", then the second and if they are not the same the second card shows for a few seconds then they return to the "non-flipped" position.

我尝试使用 SwingWorker Thread.sleep SwingTimer 但我无法让它发挥作用。使用 Thread.sleep 第二张卡不会翻转如果它是重复的,它会等待睡眠时间并消失。如果它不匹配则等待面朝下并且在睡眠定时器之后第一张卡确实翻转。无论我在哪里放置Thread.sleep都会发生这种情况。

I tried using SwingWorker, Thread.sleep and SwingTimer but I cant get it to work. With Thread.sleep the second card wont "flip" if it's a duplicate it waits the amount of sleep time and disappears. If its not a match it waits "face down" and after the sleep timer the first card does flip back. This happens regardless of where I place the Thread.sleep.

使用 Swing Timer 它似乎只是改变了计时器当我与卡片进行交互时,我最终会在激活之前翻转8张卡片。

With Swing Timer it only appears to "change the timer" while I'm interacting with the cards so I end up flipping 8 cards before it activates.

我没有运气 SwingWorker 我甚至不确定它是否适用于我正在寻找的东西。

I've had no luck with SwingWorker and I'm not even sure it will work for what I'm looking for.

这是我的代码:

    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时执行,并且该卡不匹配:

Basically what I need is for this code to execute when the counter == 1, and the card is not a match:

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

然后暂停,以便显示那段时间,最后它恢复将卡片恢复到正面朝下的位置。

Then a pause so the card is revealed for that time, and finally it resumes to returning the card to its face down position.

这是我用 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;
                    }
                }
            }
        }
    }

提前感谢任何建议

推荐答案

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

Use javax.swing.Timer to schedule a future event to trigger. This will allow you to make changes to the UI safely, as the timer is triggered within the context of the Event Dispatching Thread.

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

The problem with been able to flip multiple cards simultaneously has more to do with you not setting up a state that prevents the user from flipping cards then the use of timers.

以下示例基本上只允许一张卡每次都按组翻转。

The following example basically only allows one card to be flipped per group at a time.

一旦两个组中的卡都被翻转,计时器就会启动。当它被触发时,卡被重置。

Once a card has been flipped in both groups, the timer is started. When it is triggered, the cards are reset.

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);
        }
    }
}

这篇关于SwingWorker,Thread.sleep()或javax.swing.timer?我需要“插入暂停”。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆