I'm trying to code a memory game
and I had chosen every button with a specific color.
I want to compare these two buttons. When the user clicks the next button I want to start comparing.
I came up with comparing the color’s background.
I have tried to save the background color in a variable and test if they are the same but it doesn't enter the if
statement even if the two colors are the same.
If you have any other ideas, please help me :)
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MemoryGame implements ActionListener {
public static void main(String[] args) {
MemoryGame a = new MemoryGame();
}
ArrayList<Color> colors = new ArrayList<Color>(Arrays.asList(Color.black,
Color.BLUE,
Color.yellow,
Color.GRAY,
Color.cyan,
Color.RED,
Color.PINK,
Color.orange,
Color.orange,
Color.yellow,
Color.black,
Color.BLUE,
Color.PINK,
Color.cyan,
Color.RED,
Color.GRAY));
Random rand = new Random();
JFrame myframe = new JFrame();
JPanel title = new JPanel();
JPanel Button_Panel = new JPanel();
JButton[] buttons = new JButton[16];
JLabel textfield = new JLabel();
boolean Click1_turn = true;
MemoryGame() {
myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myframe.setSize(1000, 1000);
myframe.getContentPane().setBackground(Color.gray);
myframe.setVisible(true);
myframe.setLayout(new GridLayout()); // to put the buttons in it
Button_Panel.setLayout(new GridLayout(4, 5));
Button_Panel.setBackground(Color.black);
myframe.add(Button_Panel);
for (int i = 0; i < 16; i ) {
buttons[i] = new JButton();
Button_Panel.add(buttons[i]);
buttons[i].setFont(new Font("MV", Font.BOLD, 120));
buttons[i].setFocusable(false);
buttons[i].addActionListener(this);
}
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand());
Color Click1 = colors.get(0);
Color Click2 = colors.get(0);
for (int i = 0; i < 16; i ) {
if (e.getSource() == buttons[i]) {
if (Click1_turn) {
buttons[i].setBackground(colors.get(i));
Click1 = buttons[i].getBackground();
System.out.println("1" Click1);
Click1_turn = false;
}
else {
buttons[i].setBackground(colors.get(i));
Click2 = buttons[i].getBackground();
Click1_turn = true;
System.out.println("2" Click2);
if (Click2.equals(Click1)) {
System.out.println("ss");
}
else {
System.out.println("nah");
}
}
}
}
}
}
CodePudding user response:
JButtons, as many other UI elements have properties that are related to their screen rendering. Unless you really just need such properties, it is abuse to interprete these UI related properties as application relevant.
Create your own data model. With that you would know how many fields are on the game board and which values to put on which field (color, player, building, ...). To be clean, ensure the model does not contain any references to UI elements.
In a next step create a view of that board. It would map the fields to some UI component and ensure that one gets rendered. In your case, every button would have an ActionListener attached that knows which field is meant when the button gets clicked.
Since you probably need to compare only when the second button gets clicked you need to remember how many buttons have already been pressed, and which. All this would go into your data model.
So when a button is pressed, check if a selection is already there. If not, this selection shall be set. (it resembles the first button). If there is a selection already, compare the selected field with the second button's field, then reset the selection.
CodePudding user response:
Your logic – in method actionPerformed
– is flawed. You are resetting Click1
and Click2
to black every time method actionPerformed
is invoked, i.e. every time a JButton
is clicked.
You obviously want Click1
to keep the color it was assigned when variable Click1_turn
was true.
Therefore you should make both Click1
and Click2
class member variables, so that they keep their assigned values between separate calls to actionPerformed
.
If you run your code through a debugger, you will discover this. Note that every programmer needs to learn how to debug code, including code written by others.
Making both Click1
and Click2
class member variables is the simplest way to fix your program. Refer to the code below. Note that I changed the identifiers so as to conform to Java naming conventions.
(More notes after the code.)
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MemoryGame implements ActionListener {
private Color click1;
private Color click2;
public static void main(String[] args) {
MemoryGame a = new MemoryGame();
}
ArrayList<Color> colors = new ArrayList<Color>(Arrays.asList(Color.black,
Color.BLUE,
Color.yellow,
Color.GRAY,
Color.cyan,
Color.RED,
Color.PINK,
Color.orange,
Color.orange,
Color.yellow,
Color.black,
Color.BLUE,
Color.PINK,
Color.cyan,
Color.RED,
Color.GRAY));
Random rand = new Random();
JFrame myFrame = new JFrame();
JPanel title = new JPanel();
JPanel buttonPanel = new JPanel();
JButton[] buttons = new JButton[16];
JLabel textfield = new JLabel();
boolean click1Turn = true;
MemoryGame() {
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setSize(1000, 1000);
myFrame.getContentPane().setBackground(Color.gray);
myFrame.setVisible(true);
buttonPanel.setLayout(new GridLayout(0, 4));
buttonPanel.setBackground(Color.black);
myFrame.add(buttonPanel);
for (int i = 0; i < 16; i ) {
buttons[i] = new JButton();
buttonPanel.add(buttons[i]);
buttons[i].setFont(new Font("MV", Font.BOLD, 120));
buttons[i].setFocusable(false);
buttons[i].addActionListener(this);
}
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand());
// Color Click1 = colors.get(0);
// Color Click2 = colors.get(0);
for (int i = 0; i < 16; i ) {
if (e.getSource() == buttons[i]) {
if (click1Turn) {
buttons[i].setBackground(colors.get(i));
click1 = buttons[i].getBackground();
System.out.println("1" click1);
click1Turn = false;
}
else {
buttons[i].setBackground(colors.get(i));
click2 = buttons[i].getBackground();
click1Turn = true;
System.out.println("2" click2);
if (click2 == click1) {
System.out.println("ss");
}
else {
System.out.println("nah");
}
}
}
}
}
}
- Since all your colors are constants from class
java.awt.Color
, you can use==
to compare them rather than calling methodequals
. System.out.println(e.getActionCommand());
prints nothing since none of the buttons have a value assigned toactionCommand
.buttons[i].setFont(new Font("MV", Font.BOLD, 120));
Since you aren't setting any text for theJButton
, changing the font has no effect.Button_Panel.setLayout(new GridLayout(4, 5));
Usually better to only set one dimension, i.e.Button_Panel.setLayout(new GridLayout(0, 4));
This means that the "grid" will have exactly four columns in each row. Refer to How to Use GridLayout.myframe.setLayout(new GridLayout());
This is not necessary. The default layout is suitable.