0

** i am making a Memory Match game. the problem is the timer isnt working properly, it only increments when i press a button and does not works automatically incrementing if the user doesnt press any buttons. the timer should always increment until the user finds all the pairs. this is my board class**

package gamex;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.util.Date;
import java.util.TimeZone;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

public class Board extends JFrame{


    private List<Card> cards;
    private Card selectedCard;
    private Card c1;
    private Card c2;
    private Timer t;
    private int tries =1;
    JLabel Jtime;
    JLabel Jtries;
    int seconds;
    private SimpleDateFormat df;




    public Board(){


        int pairs = 4;
        List<Card> cardsList = new ArrayList<Card>();
        List<Integer> cardVals = new ArrayList<Integer>();

        for (int i = 0; i < pairs; i++){
            cardVals.add(i);
            cardVals.add(i);
        }
        Collections.shuffle(cardVals);

        for (int val : cardVals){
            final 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(1000, new ActionListener(){
            public void actionPerformed(ActionEvent ae){
                checkCards();


            }

        });


        t.setRepeats(false);


        setTitle("Memory Match");
        JPanel p1= new JPanel();

        p1.setLayout(new GridLayout(4, 5));
        for (Card c : cards){
            p1.add(c);
        }

        Container pane = getContentPane();
        pane.setLayout(new BorderLayout());
        pane.add(p1);

        df = new SimpleDateFormat("HH:mm:ss"); // HH for 0-23
        df.setTimeZone(TimeZone.getTimeZone("GMT"));

        Jtime = new JLabel();
        Jtime.setForeground(Color.BLACK);
        Jtime.setFont(new Font("Tahoma", Font.PLAIN, 20));
        Jtime.setPreferredSize(new Dimension(200,30));
        pane.add(Jtime,BorderLayout.NORTH);

        Jtries = new JLabel("0");
        Jtries.setForeground(Color.BLACK);
        Jtries.setFont(new Font("Tahoma", Font.PLAIN, 20));
        Jtries.setAlignmentX(50);
        Jtries.setPreferredSize(new Dimension(100,30));
        pane.add(Jtries,BorderLayout.SOUTH);


        JMenuBar mb = new JMenuBar();
        setJMenuBar(mb);
        JMenu game = new JMenu("game",true);
        game.setMnemonic('g');
        mb.add(game);
        final JMenuItem newG; 
        final JMenuItem exitG;


    game.add(newG = new JMenuItem("return to Menu       alt+r", 'r'));
    game.add(exitG = new JMenuItem("exit game                alt+e", 'e'));

    exitG.addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent ae) {
               if (ae.getSource()== exitG){
     JOptionPane.showMessageDialog(null, "Warning! your score will not be saved",
 "Warning", JOptionPane.INFORMATION_MESSAGE);
        System.exit(0);

               }
          }
      });

     newG.addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent ae) {
               if (ae.getSource()== newG){
     JOptionPane.showMessageDialog(null, "Warning! your score will not be saved",
 "Warning", JOptionPane.INFORMATION_MESSAGE);
       dispose();

               }
          }
      });



    }

    private void setTimer() {
        seconds++;
        Date d = new Date(seconds * 1000L);
        String time = df.format(d);
        Jtime.setText(time);
    }

    private void setTries(int tries){
        String tri= Integer.toString(tries);
        Jtries.setText(tri+" trie(s)");
    }

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

        }
    }

    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! "+"you did "+(tries-1)+
                        " tries to finish with the time of "+Jtime.getText());
    this.dispose();
            }
        }

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

    }

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



}

this is my card class

package gamex;

import javax.swing.JButton;


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


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

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


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

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

thank you in advance for all your help :)

kakabali
  • 3,824
  • 2
  • 29
  • 58
  • Off-topic but please do not name your variables t, c1, c2 and similar. It makes it very hard for anyone else to read and understand your code. – Joakim Danielson Apr 03 '18 at 18:03
  • Looks like your timer is running, but you only seem set the text on `Jtime` when `doTurn()` is called. Without knowing what your `Card` class implementation is like, I'm guessing that that is the button you're referring to? In any case, you'll have to refresh that label periodically, rather than only when `doTurn()` is called. – Brandon McKenzie Apr 03 '18 at 18:13
  • @Brandon McKenzie can you please clarify how to do it because im relatively new to programming. thank you in advance – nabih bassil Apr 04 '18 at 09:52
  • I would refer you to [this SO question](https://stackoverflow.com/questions/19727449/java-how-to-update-a-panel-every-second) which accomplishes a refresh every second. That solution is being used to refresh the present time, but with some [math](https://www.mkyong.com/java/how-to-calculate-date-time-difference-in-java/), you can get time elapsed off that single timer. – Brandon McKenzie Apr 04 '18 at 13:24
  • @ Brandon McKenzie sorry to say but it's giving me a NullPointerException on the CardCheck() method – nabih bassil Apr 04 '18 at 18:05

0 Answers0