2

hi there i am working on a project(card matching game) and it is almost finished but the things is when i clicked on second button to open the picture if it not same with first it suddenly closed. well nothings is wrong but user must see the picture for a while(maybe 2 second). so i used Thread.sleep(2000) but i doesnt work properly. it sets icon null and then start to wait 2 seconds. here is my code a tried to make a SSCCE,

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 java.util.Vector;

import javax.swing.BorderFactory;
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.UIManager;
import javax.swing.border.*;

public class ConcentrationGame3 extends JFrame {

    /**
     * 
     */
    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;
    int k=0;

    private Icon img[] = {UIManager.getIcon("OptionPane.errorIcon"),
            UIManager.getIcon("OptionPane.informationIcon"),
            UIManager.getIcon("OptionPane.warningIcon")};

    private Icon iconList[] = new ImageIcon[size];

    public ConcentrationGame3(){

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

        for(i=0; i<4; i++){

            final GameButton button = new GameButton(new JToggleButton(),iconList[i]);
            button.addItemListener(new ItemListener(){
                public void itemStateChanged(ItemEvent e){

                    button.setState();
                }
            });

            button.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent e){

                        try {
                            buttonActionPerformed(e,button);
                        } catch (InterruptedException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }
                }
            });
            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);
    }

    class GameButton extends JToggleButton{

        private static final long serialVersionUID = 1L;
        private JToggleButton gameButton;
        private Icon icon;

        public GameButton(JToggleButton gameButton,Icon icon){

            this.gameButton = gameButton;
            this.icon = icon;
        }

         public void setState() {
                if (this.isSelected() || !this.isEnabled()) {
                    this.setIcon(icon);
                } else {
                    this.setIcon(hidden);
                }
            }
        }

    private void buttonActionPerformed(ActionEvent e, GameButton button) throws InterruptedException {
        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{
                            Thread.sleep(2000);
                            buttonFirst.setIcon(hidden);
                            buttonFirst.setSelected(false);
                            buttonSecond.setIcon(hidden);
                            buttonSecond.setSelected(false);

                    }

            }
        }
    }

    private void retirePair(GameButton a, GameButton b){
        a.setSelected(true);
        a.setEnabled(false);
        b.setSelected(true);
        b.setEnabled(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; j<arr.length; j++){

            if(arr[j] == rnd){
                counter++;
                if(counter>1)
                    return true;
            }
        }

        return false;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {

        new ConcentrationGame3();

    }

}

i appreciated if you can help me. and thanks anyway :)

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
quartaela
  • 2,579
  • 16
  • 63
  • 99
  • 1
    No, you didn't make it a SSCCE; you dumped all your code in the question and asked "What's wrong?" – Brian Roach Oct 27 '11 at 01:03
  • 2
    It seems strange to me that your `GameButton extends JToggleButton` but also requires a `JToggleButton` to be constructed by its clients for the constructor -- and _stores_ a `JToggleButton` too. From what I recall of Java, `extends` is a "is-a" relationship, but you're using it as if it were a "has-a" relationship. – sarnold Oct 27 '11 at 01:07
  • @Brian well yeah but this code has 100 lines more and pictures which i use specially on my computer. and i am not asking like "ok whats wrong give me the code please". read carefully... – quartaela Oct 27 '11 at 01:08
  • I'm not sure why this is tagged with multithreading when there is only one thread. Perhaps you ought to have multiple threads. – Keith Irwin Oct 27 '11 at 01:09
  • It is at least a smaller version of the whole -- I'll give credit (and 1+ for that), and allowed me to easily test a working solution before posting an answer. – Hovercraft Full Of Eels Oct 27 '11 at 01:10
  • @Keith yeap i just wrote thread and press enter it changed by itself and i couldnt fine onyl just "thread" – quartaela Oct 27 '11 at 01:11
  • @quartaela, it's less about "regulations" and more about programming exactly what you _mean_: should your `GameButton` _derive_ from `JToggleButton` or should `GameButton` _include_ a `JToggleButton`? Your current code tries to do _both_, when it should do only _one_. Having code around that tries to do both is going to be a source of bugs, even if it isn't at all related to the bug that our esteemed Hovercraft has found. ;) – sarnold Oct 27 '11 at 22:42
  • @sarnold ok i guess i fixed the problem with no sending `new JToggleButton()` i just send icon. is it true_? – quartaela Oct 28 '11 at 15:50
  • @quartaela, that sounds much better! – sarnold Oct 28 '11 at 23:24

1 Answers1

6

You don't want to use Thread.sleep on the Swing thread, since as I'm sure you've read if you've done any searching, what this does is put Swing to sleep, sleep meaning all drawing is frozen, and all user interaction (like response to buttons) is frozen. Instead use a Swing Timer which will allow you to pause your application without preventing Swing from drawing your second image and showing both for 2 or 3 seconds. The logic will be: show both images, start the timer, and when the timer "ticks" after 2 or 3 seconds (or whatever you set the delay to be), hide the images inside of the timer's ActionListener.

Also: make sure that you set the timer as non-repeating (there's a boolean method of Swing Timer that does this). Also, you'll want to make all of your JToggleButtons unresponsive (or enabled == false) while the the two images are shown, and then you want the Timer to set all the non-paired buttons to a responsive state when it "ticks".

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • @quartaela: Have this link bookmarked: [The Really Big Index](http://download.oracle.com/javase/tutorial/reallybigindex.html). Then search on that page for Swing Timers. – Hovercraft Full Of Eels Oct 27 '11 at 01:16