0

I am currently trying to program a memory/matching game. I am having a problem with trying to figure out how to disable the button after the user has found matching cards. I understand that I need to store the value of the first click and compare it to the second click but still unsure about how it is not working... If anyone could help it would be very appreciated. Thanks.

Consider this code, i have recreated a more simple version of the game which you can actually run below:

main:

public static void main(String[] args) {
        start start = new start();
        start.main();
    }

}

Class for the frame:

class start {

    JToggleButton DisplayCards[][] = new JToggleButton[4][4];
    Shuffle shuffle = new Shuffle();

    void main() {
        JFrame frame = new JFrame();

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 600);
        int y = 20;
        int x = 60;

        for (int i = 0; i < DisplayCards.length; ++i) {
            for (int j = 0; j < DisplayCards[i].length; ++j) {
                DisplayCards[i][j] = new JToggleButton("Click Me!");

                DisplayCards[i][j].setBounds(x, y, 90, 126);
                y = y + 135;
                if (y >= 540) {
                    y = 20;
                    x = x + 120;
                }
                frame.add(DisplayCards[i][j]);
                DisplayCards[i][j].addActionListener(new Clicked(i, j, shuffle));
            }
        }

        frame.setLayout(null);
        frame.setVisible(true);
    }
}

Class that shuffles array:

class Shuffle {

    String[][] cards = {
        {"A", "B", "C", "D"},
        {"E", "F", "G", "H"},
        {"A", "B", "C", "D"},
        {"E", "F", "G", "H"}

    };

    public void random() {
        for (int i = 0; i < cards.length; i++) {
            for (int j = 0; j < cards[i].length; j++) {
                int i1 = (int) (Math.random() * cards.length);
                int j1 = (int) (Math.random() * cards[i].length);

                String temp = cards[i][j];
                cards[i][j] = cards[i1][j1];
                cards[i1][j1] = temp;
            }

        }
    }
}

Class for the ActionListener:

class Clicked implements ActionListener {

    String first;
    start matching = new start();
    boolean state = false;
    Shuffle shuffle;
    JToggleButton tBtn;
    private int i;
    private int j;
    int posI;
    int posJ;

    public Clicked(int i, int j, Shuffle shuffle) {
        this.i = i;
        this.j = j;
        this.shuffle = shuffle;
    }

    public void actionPerformed(ActionEvent e) {
        tBtn = (JToggleButton) e.getSource();
        if (tBtn.isSelected()) {
            tBtn.setText(shuffle.cards[i][j]);
            if (!state) {
                first = shuffle.cards[i][j];
                posI = i;
                posJ = j;
                System.out.println(first);
                state = true;

            } else {
                if (first.equals(shuffle.cards[i][j])) {
                    tBtn.setEnabled(false);
                    System.out.println("Correct!");
                } else if (!first.equals(shuffle.cards[i][j])) {
                    System.out.println("Not it");
                    tBtn.setText("Click Me!");
                    matching.DisplayCards[posI][posJ].setText("Click Me!");
                    first = null;
                    posI = 0;
                    posJ = 0;
                    state = false;
                }
            }
        } else {
            tBtn.setText("Click Me!");
        }
    }
}
c0der
  • 18,467
  • 6
  • 33
  • 65
  • 1
    1) Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). This looks suited to a `GridLayout` – Andrew Thompson Jan 19 '20 at 01:39
  • 1
    2) *"a more simple version of the game which you can actually run"* There are missing imports, incomplete classes, and missing classes. For better help sooner, [edit] to add a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 3) Please learn common Java nomenclature (naming conventions - e.g. `EachWordUpperCaseClass`, `firstWordLowerCaseMethod()`, `firstWordLowerCaseAttribute` unless it is an `UPPER_CASE_CONSTANT`) and use it consistently. – Andrew Thompson Jan 19 '20 at 01:40
  • Welcome to Stack Overflow. Please see: [Why is “Can someone help me?” not an actual question?](http://meta.stackoverflow.com/q/284236) – Progman Jan 19 '20 at 10:10

1 Answers1

1

The following is one-file mre (copy paste the entire code into `Start.java' and run).
Please note the comments:

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JToggleButton;

//Java Naming Conventions: https://www.geeksforgeeks.org/java-naming-conventions/
public class Start {

    JToggleButton displayCards[][] = new JToggleButton[4][4];
    Shuffle shuffle = new Shuffle();
    private static final int NO_PREVIOUS = -1;
    //static fileds for i,j of previous button clicked
    private int previousI = NO_PREVIOUS, previousJ = NO_PREVIOUS;

    void main() {
        JFrame frame = new JFrame();

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 600);
        int y = 20, x = 60;

        for (int i = 0; i < displayCards.length; ++i) {
            for (int j = 0; j < displayCards[i].length; ++j) {
                displayCards[i][j] = new JToggleButton("Click Me!");

                displayCards[i][j].setBounds(x, y, 90, 126);
                y = y + 135;
                if (y >= 540) {
                    y = 20;
                    x = x + 120;
                }
                frame.add(displayCards[i][j]);
                displayCards[i][j].addActionListener(new Clicked(i, j, shuffle));
            }
        }

        frame.setLayout(null); //avoid null layout :https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Start Start = new Start();
        Start.main();
    }

    //to have easy access to Start members make the ActionListener an inner class
    class Clicked implements ActionListener {

        private static final String HIDE_TEXT = "Click Me!";
        private final Shuffle shuffle;
        private final int i, j;

        public Clicked(int i, int j, Shuffle shuffle) {
            this.i = i;
            this.j = j;
            this.shuffle = shuffle;
        }

        @Override
        public void actionPerformed(ActionEvent e) {

            JToggleButton tBtn = (JToggleButton) e.getSource();
            showButtonText(tBtn, i, j);

            if( previousI == NO_PREVIOUS || previousJ == NO_PREVIOUS){ //no previous selected btn
                previousI = i;
                previousJ = j;
                return;
            }

            JToggleButton previous = displayCards[previousI][previousJ]; //reference to previous button clicked

            if(match(tBtn, previous)){
                 matchFound(tBtn, previous);
            }else{
                matchNotFound(tBtn, previous);
            }
        }

        private void showButtonText(JToggleButton btn, int i, int j) {
            btn.setText(shuffle.cards[i][j]);
            btn.setEnabled(false);
        }

        private void resetButton(JToggleButton btn) {
            btn.setForeground(Color.BLACK);
            btn.setText(HIDE_TEXT);
            btn.setSelected(false);
            btn.setEnabled(true);
        }

        private boolean match(JToggleButton btn1, JToggleButton btn2) {
            return btn1.getText().equals(btn2.getText());
        }

        private void matchFound(JToggleButton btn1, JToggleButton btn2) {
            System.out.println("Correct!");
            btn1.setEnabled(false);
            btn2.setEnabled(false);
            previousI = NO_PREVIOUS ; previousJ = NO_PREVIOUS;
        }

        private void matchNotFound(JToggleButton tBtn, JToggleButton previous) {
            System.out.println("No match");
            resetButton(previous);
            previousI = i ; previousJ = j;
        }
    }
}

class Shuffle {

    String[][] cards = {
        {"A", "B", "C", "D"},
        {"E", "F", "G", "H"},
        {"A", "B", "C", "D"},
        {"E", "F", "G", "H"}

    };

    public void random() {
        for (int i = 0; i < cards.length; i++) {
            for (int j = 0; j < cards[i].length; j++) {
                int i1 = (int) (Math.random() * cards.length);
                int j1 = (int) (Math.random() * cards[i].length);

                String temp = cards[i][j];
                cards[i][j] = cards[i1][j1];
                cards[i1][j1] = temp;
            }

        }
    }
}


A better implementation using GridLayout instead of null layout:
public class Start {

    //static fileds for i,j of previous button clicked
    private int previousI = NO_PREVIOUS, previousJ = NO_PREVIOUS;
    private static final String HIDE_TEXT = "Click Me!";
    private static final int W = 96, H = 126, NO_PREVIOUS = -1, SIZE = 4, GAP = 5;

    JToggleButton displayCards[][] = new JToggleButton[SIZE][SIZE];
    Shuffle shuffle = new Shuffle();

    Start() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel board = new JPanel();
        board.setLayout(new GridLayout(displayCards.length, displayCards[0].length, GAP, GAP));

        for (int i = 0; i < displayCards.length; ++i) {
            for (int j = 0; j < displayCards[i].length; ++j) {
                JToggleButton btn = new JToggleButton(HIDE_TEXT);
                btn.setPreferredSize(new Dimension(W,H));
                btn.addActionListener(new Clicked(i, j, shuffle));
                displayCards[i][j] = btn;
                board.add(btn);
            }
        }

        frame.add(board);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new Start();
    }

    //to have easy access to Start members make the ActionListener an inner class
    class Clicked implements ActionListener {

        private final Shuffle shuffle;
        private final int i, j;

        public Clicked(int i, int j, Shuffle shuffle) {
            this.i = i;
            this.j = j;
            this.shuffle = shuffle;
        }

        @Override
        public void actionPerformed(ActionEvent e) {

            JToggleButton tBtn = (JToggleButton) e.getSource();
            showButtonText(tBtn, i, j);

            if( previousI == NO_PREVIOUS || previousJ == NO_PREVIOUS){ //no previous selected btn
                previousI = i;
                previousJ = j;
                return;
            }

            JToggleButton previous = displayCards[previousI][previousJ]; //reference to previous button clicked

            if(match(tBtn, previous)){
                 matchFound(tBtn, previous);
            }else{
                matchNotFound(tBtn, previous);
            }
        }

        private void showButtonText(JToggleButton btn, int i, int j) {
            btn.setText(shuffle.cards[i][j]);
            btn.setEnabled(false);
        }

        private void resetButton(JToggleButton btn) {
            btn.setForeground(Color.BLACK);
            btn.setText(HIDE_TEXT);
            btn.setSelected(false);
            btn.setEnabled(true);
        }

        private boolean match(JToggleButton btn1, JToggleButton btn2) {
            return btn1.getText().equals(btn2.getText());
        }

        private void matchFound(JToggleButton btn1, JToggleButton btn2) {
            System.out.println("Correct!");
            btn1.setEnabled(false);
            btn2.setEnabled(false);
            previousI = NO_PREVIOUS ; previousJ = NO_PREVIOUS;
        }

        private void matchNotFound(JToggleButton tBtn, JToggleButton previous) {
            System.out.println("No match");
            resetButton(previous);
            previousI = i ; previousJ = j;
        }
    }
}
c0der
  • 18,467
  • 6
  • 33
  • 65