Home > Enterprise >  How to add pictures to memory game in java
How to add pictures to memory game in java

Time:09-14

How to add pictures to memory game? I made it like a number game and now want to add pictures so that players can play a picture flip memory game. I have attached the code, and Board.java is somewhere changes are needed. I am really stuck on this one, any help will be appreciated.

Code.java

import javax.swing.JButton;

public class Card extends JButton{
    private String id;
    private boolean matched = false;


    public void setId(String val){
        this.id = val;
    }

    public String getId(){
        return this.id;
    }


    public void setMatched(boolean matched){
        this.matched = matched;
    }

    public boolean getMatched(){
        return this.matched;
    }
}

Game.java

import java.awt.Dimension;
import javax.swing.JFrame;

public class Game{
    public static void main(String[] args){
        Board b = new Board();
        b.setPreferredSize(new Dimension(500,500)); //need to use this instead of setSize
        b.setLocation(500, 250);
        b.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        b.pack();
        b.setVisible(true);
    }   
}

Board.java

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;

public class Board extends JFrame{
    private List<Card> cards;
    private Card selectedCard;
    private Card c1;
    private Card c2;
    private Timer t;
    static String fruits[] = {"pear.jpg", "peach.jpg", "pineapple.jpg", "/apple.jpg",
    "avocado.jpg", "/greenapple.jpg"};
    static String files[] = fruits;

    public Board(){

        int pairs = 14;
        List<Card> cardsList = new ArrayList<Card>();
        List<String> cardVals = new ArrayList<String>();

        for (int i = 0; i < pairs; i  ){
            cardVals.add(i, fruits[i]);
            cardVals.add(i, fruits[i]);
        }
        Collections.shuffle(cardVals);

        for (String val : cardVals){
            Card c = new Card();
            c.setId(val);
            c.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent ae){
                    selectedCard = c;
                    doTurn();
                }
            });
            cardsList.add(c);
        }
        this.cards = cardsList;
        //set up the timer
        t = new Timer(750, new ActionListener(){
            public void actionPerformed(ActionEvent ae){
                checkCards();
            }
        });

        t.setRepeats(false);

        //set up the board itself
        Container pane = getContentPane();
        pane.setLayout(new GridLayout(4, 5));
        for (Card c : cards){
            pane.add(c);
        }
    }

    public void doTurn(){
        if (c1 == null && c2 == null){
            c1 = selectedCard;
            c1.setText(String.valueOf(c1.getId()));
        }

        if (c1 != null && c1 != selectedCard && c2 == null){
            c2 = selectedCard;
            c2.setText(String.valueOf(c2.getId()));
            t.start();

        }
    }

    public void checkCards(){
        if (c1.getId() == c2.getId()){//match condition
            c1.setEnabled(false); //disables the button
            c2.setEnabled(false);
            c1.setMatched(true); //flags the button as having been matched
            c2.setMatched(true);
            if (this.isGameWon()){
                JOptionPane.showMessageDialog(this, "You win!");
                System.exit(0);
            }
        }

        else{
            c1.setText(""); //'hides' text
            c2.setText("");
        }
        c1 = null; //reset c1 and c2
        c2 = null;
    }

    public boolean isGameWon(){
        for(Card c: this.cards){
            if (c.getMatched() == false){
                return false;
            }
        }
        return true;
    }

}

CodePudding user response:

First line in method checkCards is:

if (c1.getId() == c2.getId()){//match condition

It should be:

if (c1.getId().equals(c2.getId())){

Refer to How do I compare strings in Java?

You don't need a class that extends JButton. A Component has a name so use methods setName(String) and getName() rather than adding an ID field. Also, a JComponent supports custom properties so make the matched flag a custom property.

The first for loop, in the constructor of class Board, throws ArrayIndexOutOfBoundsException since you only have six images in array fruits. I assume that you want each image to appear on two different cards. The loop should be:

for (int i = 0; i < fruits.length; i  ){
    cardVals.add(fruits[i]);
    cardVals.add(fruits[i]);
}

Refer to the javadoc for methods add(E) and add(int, E). Method add(E) simply adds to the end of the list.

So now you want the JButtons to show an icon rather than text. So first you need to create the icons. Initially, none of the JButtons has an icon. Then, when the user clicks on a JButton you want to add an appropriate icon to it. You also need to be able to remove the icon. You can do this via method setIcon. If the method parameter is null, the icon is removed and when the parameter is not null, an icon is added to the JButton.

I use a Map to associate a JButton with its icon. The Map key is the ID attribute in your Card class and the Map value is the actual icon.

To keep things simple, I added all the icon files to the same package as your Board class. Refer to How to Use Icons for more details about creating icons in Swing.

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Collections;
import java.util.HashMap;

public class Board extends JFrame {
    private static final String  MATCHED = "MATCHED";
    private static final Map<String, Icon>  ICONS;

    private List<JButton> cards;
    private JButton selectedCard;
    private JButton c1;
    private JButton c2;
    private Timer t;
    static String fruits[] = {"pear.png",
                              "peach.png",
                              "pineapple.png",
                              "apple.png",
                              "avocado.png",
                              "greenapple.png"};
    static String files[] = fruits;

    static {
        ICONS = new HashMap<>(fruits.length);
        Class<?> theClass = Board.class;
        for (int i = 0; i < fruits.length; i  ) {
            ICONS.put(fruits[i], new ImageIcon(theClass.getResource(fruits[i])));
        }
    }

    public Board() {
        List<JButton> cardsList = new ArrayList<JButton>();
        List<String> cardVals = new ArrayList<String>();
        for (int i = 0; i < fruits.length; i  ){
            cardVals.add(fruits[i]);
            cardVals.add(fruits[i]);
        }
        Collections.shuffle(cardVals);
        for (String val : cardVals){
            JButton c = new JButton();
            c.setName(val);
            c.putClientProperty(MATCHED, Boolean.FALSE);
            c.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent ae){
                    selectedCard = c;
                    doTurn();
                }
            });
            cardsList.add(c);
        }
        this.cards = cardsList;
        //set up the timer
        t = new Timer(750, new ActionListener(){
            public void actionPerformed(ActionEvent ae){
                checkCards();
            }
        });
        t.setRepeats(false);
        //set up the board itself
        Container pane = getContentPane();
        pane.setLayout(new GridLayout(4, 5));
        for (JButton c : cards){
            pane.add(c);
        }
    }

    public void doTurn(){
        if (c1 == null && c2 == null){
            c1 = selectedCard;
            c1.setIcon(ICONS.get(c1.getName()));
        }
        if (c1 != null && c1 != selectedCard && c2 == null){
            c2 = selectedCard;
            c2.setIcon(ICONS.get(c2.getName()));
            t.start();
        }
    }

    public void checkCards(){
        if (c1.getName().equals(c2.getName())) { //match condition
            c1.setEnabled(false); //disables the button
            c2.setEnabled(false);
            c1.putClientProperty(MATCHED, Boolean.TRUE); //flags the button as having been matched
            c2.putClientProperty(MATCHED, Boolean.TRUE);
            if (this.isGameWon()){
                JOptionPane.showMessageDialog(this, "You win!");
                System.exit(0);
            }
        }
        else{
            c1.setIcon(null); //'hides' text
            c2.setIcon(null);
        }
        c1 = null; //reset c1 and c2
        c2 = null;
    }

    public boolean isGameWon() {
        for (JButton c : cards) {
            if (c.getClientProperty(MATCHED) == Boolean.FALSE) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        Board b = new Board();
        b.setPreferredSize(new Dimension(500,500)); //need to use this instead of setSize
        b.setLocation(500, 250);
        b.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        b.pack();
        b.setVisible(true);
    }
}

Note that I downloaded my own icons from the Internet, hence the names don't exactly match your names. Also, I placed all the PNG files in the same directory as file Board.class (i.e. the file created when compiling the Java source code).

  • Related