javaswinguser-interfacejtogglebutton

Timer does not start when implementing memory game with JToggleButton


I am trying to create a memory game where you have 12 togglebuttons. If you click one button, the icon would change. If two icons match then both are flipped. However, if they do not match, then a timer starts for 1.5 secs then switch both togglebuttons back to main icon "MemoryGame.png". This is what I have:

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Arrays;
import javax.swing.*;
import java.util.Collections;

public class MemoryGame extends JToggleButton implements ActionListener {

private Timer cdTimer;
private Timer swTimer;
private int count = 1;
private JToggleButton[] buttons;
private String[] commandID = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"};
ArrayList<ImageIcon> iconList = new ArrayList();
ImageIcon icon = new ImageIcon("MemoryGame.png");

public MemoryGame() {
    JFrame jfrm = new JFrame();

    jfrm.setSize(1000, 1000);

    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    GridLayout layout = new GridLayout(3,4);

    JPanel gamePanel = new JPanel();
    gamePanel.setLayout(layout);

    JPanel timerPanel;

    createIcons();

    buttons = new JToggleButton[12];

    for(int i = 0; i < buttons.length; i++) {
        JToggleButton btn = new JToggleButton(icon);

        buttons[i] = btn;

        buttons[i].setActionCommand(commandID[i]);

        buttons[i].addActionListener(this);

        gamePanel.add(buttons[i]);   
    }

    //Collections.shuffle(Arrays.asList(buttons));

    jfrm.add(gamePanel, BorderLayout.CENTER);

    jfrm.setLocationRelativeTo(null);

    jfrm.setVisible(true);
}

public void actionPerformed(ActionEvent e){
    JToggleButton btn = (JToggleButton)e.getSource();
    JToggleButton btn2 = (JToggleButton)e.getSource();

    firstClick(btn, btn2);
    secondClick(btn, btn2);
    matching(btn, btn2);
}     

private void firstClick(JToggleButton btn, JToggleButton btn2) {
    if(btn == buttons[0] || btn == buttons[1])
        btn.setIcon(iconList.get(0)); 

    else if(btn == buttons[2] || btn == buttons[3])
        btn.setIcon(iconList.get(1));

    else if(btn == buttons[4] || btn == buttons[5])
        btn.setIcon(iconList.get(2));

    else if(btn == buttons[6] || btn == buttons[7])
        btn.setIcon(iconList.get(3));

    else if(btn == buttons[8] || btn == buttons[9])
        btn.setIcon(iconList.get(4));

    else if(btn == buttons[10] || btn == buttons[11])
        btn.setIcon(iconList.get(5));
}

private void secondClick(JToggleButton btn, JToggleButton btn2){
    if(btn2 != btn && btn2 == buttons[0] || btn2 == buttons[1])
        btn.setIcon(iconList.get(0));

    else if(btn2 != btn && btn2 == buttons[2] || btn2 == buttons[3])
        btn.setIcon(iconList.get(1));

    else if(btn2 != btn && btn2 == buttons[4] || btn2 == buttons[5])
        btn.setIcon(iconList.get(2));

    else if(btn2 != btn && btn2 == buttons[6] || btn2 == buttons[7]) 
        btn.setIcon(iconList.get(3));

    else if(btn2 != btn && btn2 == buttons[8] || btn2 == buttons[9])
        btn.setIcon(iconList.get(4));

    else if(btn2 != btn && btn2 == buttons[10] || btn2 == buttons[11])
        btn.setIcon(iconList.get(5));
}

private void matching(JToggleButton btn, JToggleButton btn2){
    if(btn.isSelected()){
        btn.setEnabled(false);
        if(btn2.isSelected()){
            btn2.setEnabled(false);
            if(!btn.getIcon().toString().equals(btn2.getIcon().toString())){
                startTime(1, btn, btn2);
            }
            else
                retirePair(btn, btn2);           
        }
    }   
}

private void startTime(int countPassed, JToggleButton button, JToggleButton button2){
    ActionListener action = new ActionListener(){
        public void actionPerformed(ActionEvent e){
            if(count == 0){
                cdTimer.stop();
                button.setIcon(icon);
                button2.setIcon(icon);
                button.setEnabled(true);
                button2.setEnabled(true);
                button.setSelected(false);
                button2.setSelected(false);
            }
            else
                count--;
            }

    };
    cdTimer = new Timer(500, action);
    cdTimer.start();
    count = countPassed;
}

private void unflipPair(JToggleButton btn, JToggleButton btn2){
    btn.setEnabled(true);
    btn2.setEnabled(true);
    btn.setSelected(false);
    btn2.setSelected(false);
}

private void retirePair(JToggleButton btn, JToggleButton btn2){
    btn.setEnabled(false);
    btn2.setEnabled(false);
    btn.setSelected(true);
    btn2.setSelected(true);
}

private void createIcons(){
    ImageIcon icon1 = new ImageIcon("1.png");
    ImageIcon icon2 = new ImageIcon("2.png");
    ImageIcon icon3 = new ImageIcon("3.png");
    ImageIcon icon4 = new ImageIcon("4.png");
    ImageIcon icon5 = new ImageIcon("5.png");
    ImageIcon icon6 = new ImageIcon("6.png");

    iconList.add(icon1);
    iconList.add(icon2);
    iconList.add(icon3);
    iconList.add(icon4);
    iconList.add(icon5);
    iconList.add(icon6);
}

The problem I am having is the timer does not start at all; therefore, the icons remain the same and do not flip back even when they don't match. Is there a way to make this work? Thank you


Solution

  • This...

    public void actionPerformed(ActionEvent e){
        JToggleButton btn = (JToggleButton)e.getSource();
        JToggleButton btn2 = (JToggleButton)e.getSource();
    
        firstClick(btn, btn2);
        secondClick(btn, btn2);
        matching(btn, btn2);
    }     
    

    Doesn't make sense in the context of the rest f the code, as btn and btn2 are the same thing.

    Instead, when actionPerformed is called, you need to determine if any button has been previous actioned, if it has, then this is likely the second button and you need to compare them, if it's not, it's likely the first button and you need to wait for the second one.

    Maybe something like...

    private JToggleButton lastButton;
    
    public void actionPerformed(ActionEvent e){
        if (lastButton == null) {
            lastButton = (JToggleButton)e.getSource();
            return;
        }
    
        JToggleButton btn = (JToggleButton)e.getSource();
    
        firstClick(btn, lastButton);
        secondClick(btn, lastButton);
        matching(btn, lastButton);
    
        lastButton = null;
    }     
    

    would be a better starting point (nb I've not run the rest of the code, but this is such a glaringly obvious issue, it needs to be fixed before any further testing can be done)

    Update - After a little bit of testing, this will at least get the timer to fire

    Updated...

    Hello, so I tried it. However, the buttons still did not flip

    The basic fix should get you moving, but I had to make a number of other changes to make it work the way you're expecting

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.ArrayList;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JToggleButton;
    import javax.swing.Timer;
    
    public class MemoryGame extends JToggleButton implements ActionListener {
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new MemoryGame();
                }
            });
        }
    
        private Timer cdTimer;
        private JToggleButton[] buttons;
        ArrayList<String> iconList = new ArrayList();
    
        public MemoryGame() {
            JFrame jfrm = new JFrame();
    
            jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            GridLayout layout = new GridLayout(3, 4);
    
            JPanel gamePanel = new JPanel();
            gamePanel.setLayout(layout);
    
            createIcons();
    
            buttons = new JToggleButton[12];
    
            for (int i = 0; i < buttons.length; i++) {
                JToggleButton btn = new JToggleButton("~");
                btn.setFocusable(false);
    
                buttons[i] = btn;
    
    //            buttons[i].setActionCommand(commandID[i]);
                buttons[i].addActionListener(this);
    
                gamePanel.add(buttons[i]);
            }
    
            //Collections.shuffle(Arrays.asList(buttons));
            jfrm.add(gamePanel, BorderLayout.CENTER);
    
            jfrm.pack();
            jfrm.setLocationRelativeTo(null);
    
            jfrm.setVisible(true);
        }
    
        private JToggleButton last;
    
        public void actionPerformed(ActionEvent e) {
            JToggleButton btn = (JToggleButton) e.getSource();
            firstClick(btn);
            if (last == null) {
                last = btn;
                return;
            }
    
            matching(btn, last);
    
            last = null;
        }
    
        private void firstClick(JToggleButton btn) {
            if (btn == buttons[0] || btn == buttons[1]) {
                btn.setText(iconList.get(0));
            } else if (btn == buttons[2] || btn == buttons[3]) {
                btn.setText(iconList.get(1));
            } else if (btn == buttons[4] || btn == buttons[5]) {
                btn.setText(iconList.get(2));
            } else if (btn == buttons[6] || btn == buttons[7]) {
                btn.setText(iconList.get(3));
            } else if (btn == buttons[8] || btn == buttons[9]) {
                btn.setText(iconList.get(4));
            } else if (btn == buttons[10] || btn == buttons[11]) {
                btn.setText(iconList.get(5));
            }
        }
    
        private void matching(JToggleButton btn, JToggleButton btn2) {
            if (btn.isSelected()) {
                btn.setEnabled(false);
                if (btn2.isSelected()) {
                    btn2.setEnabled(false);
                    if (!btn.getText().equals(btn2.getText())) {
                        startTime(btn, btn2);
                    } else {
                        retirePair(btn, btn2);
                    }
                }
            }
        }
    
        private void startTime(JToggleButton button, JToggleButton button2) {
            System.out.println("!!");
            ActionListener action = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.out.println("..");
                    cdTimer.stop();
                    button.setText("~");
                    button2.setText("~");
                    button.setEnabled(true);
                    button2.setEnabled(true);
    
                    button.setSelected(false);
                    button2.setSelected(false);
                }
    
            };
            cdTimer = new Timer(1000, action);
            cdTimer.start();
        }
    
        private void unflipPair(JToggleButton btn, JToggleButton btn2) {
            btn.setEnabled(true);
            btn2.setEnabled(true);
            btn.setSelected(false);
            btn2.setSelected(false);
        }
    
        private void retirePair(JToggleButton btn, JToggleButton btn2) {
            btn.setEnabled(false);
            btn2.setEnabled(false);
            btn.setSelected(true);
            btn2.setSelected(true);
        }
    
        private void createIcons() {
            ImageIcon icon1 = new ImageIcon("1.png");
            ImageIcon icon2 = new ImageIcon("2.png");
            ImageIcon icon3 = new ImageIcon("3.png");
            ImageIcon icon4 = new ImageIcon("4.png");
            ImageIcon icon5 = new ImageIcon("5.png");
            ImageIcon icon6 = new ImageIcon("6.png");
    
            iconList.add("1");
            iconList.add("2");
            iconList.add("3");
            iconList.add("4");
            iconList.add("5");
            iconList.add("6");
    
        }
    
    }