JAVA Simon Game - java

I need to finish up this simon game for my beginner Java class. Basically the game needs to randomize 3 of the COLOR letters on the top label "R", "B", "Y" or "G" to begin playing the game. The player will press the colors in this sequence and if they are correct it will add another letter/color if they are wrong they will lose. I have the main part of the game set up including color ect... What I am having a hard time with is printing the letters of the buttons pushed on the bottom label and also getting the top label to randomize 3 to start with. I can get the game to print random letters on the top label when a button is pushed but it wont do this own its own to start and it wont add the letters on?
HERE IS MY CODE:
//10/30/16
package simongame1;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.security.SecureRandom;
public class SimonGame1 extends JFrame implements ActionListener
{
public SecureRandom rand;
public String randomLetters="";
JButton[] numberButtons = new JButton[4];
JPanel numberButtonPanel = new JPanel();
JLabel labelTop;
JLabel labelBottom;
String messageTop = "";
String messageBottom = "";
JButton red;
JButton green;
JButton yellow;
JButton blue;
public final String letters= "RGBY";
public JLabel labelDisplay;
//constructor?
public SimonGame1()
{
super("Simon Game!");
labelDisplay = new JLabel ("");
setLayout(new BorderLayout());
red = new JButton();
green = new JButton();
blue = new JButton();
yellow = new JButton();
labelTop = new JLabel("");
//getRandomLetter();
labelBottom = new JLabel("");
//System.out.print (randomLetters);
rand = new SecureRandom();
numberButtons = new JButton[4];
numberButtonPanel = new JPanel();
numberButtonPanel.setLayout(new GridLayout(3,3));
for(int i = 0; i < 0; i++)
{
numberButtons[i] = new JButton();
numberButtonPanel.add(numberButtons[i]);
numberButtons[i].addActionListener(this);
}
numberButtonPanel.add(red);
red.setBackground(Color.red);
red.addActionListener(this);
numberButtonPanel.add(blue);
blue.setBackground(Color.blue);
blue.addActionListener(this);
numberButtonPanel.add(yellow);
yellow.setBackground (Color.yellow);
yellow.addActionListener(this);
numberButtonPanel.add (green);
green.setBackground (Color.green);
green.addActionListener(this);
add(labelTop, BorderLayout.NORTH);
add(labelBottom, BorderLayout.SOUTH);
add(numberButtonPanel, BorderLayout.CENTER);
//if (messageTop = messageBottom)
}
// TODO code application logic here
#Override
public void actionPerformed(ActionEvent e)
{
rand = new SecureRandom();
randomLetters+= getRandomLetter();
labelTop.setText (randomLetters);
labelBottom.setText (letters);
System.out.println(e.getID());
if(e.getSource() == red)
{
System.out.println("R");
}
else if (e.getSource()==blue)
{
System.out.println ("B");
}
else if (e.getSource()==yellow)
{
System.out.println ("Y");
}
else if (e.getSource()==green)
{
System.out.println ("G");
}
}
public char getRandomLetter()
{
char randChar = letters.charAt(rand.nextInt (4));
return randChar;
}
}
AND HERE IS THE TEST
package simongame1;
import javax.swing.JFrame;
public class NewClass {
public static void main(String[] args) {
{
SimonGame1 simpleFrame = new SimonGame1();
simpleFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
simpleFrame.setSize(300, 300);
simpleFrame.setVisible(true);
}
}
}
WHY IS THIS ONE CLICK BEHIND? If i click the red button it doenst show anything but if i click the blue one after the red thats when it prints "R" finally...
labelBottom.setText (messageBottom);
**//WHY IS IT ONE LETTER BEHIND?**
System.out.println(e.getID());
if(e.getSource() == red)
{
messageBottom += "R";
//System.out.println("R");
}
else if (e.getSource()==blue)
{
messageBottom += "B";
//System.out.println ("B");
}
else if (e.getSource()==yellow)
{
messageBottom += "Y";
//System.out.println ("Y");
}
else if (e.getSource()==green)
{
messageBottom += "G";
//System.out.println ("G");
}

When you initialize your label, before you add it to the panel I would just generate the label with the letters you need and set the text of the label right there. That way when you add it you will for sure have the characters in there. Right now you are only setting the text of labelTop when the actionPerformed method is called, which is only called when a button is pressed.
So it should look something like:
public SimonGame1() {
//....
rand = new SecureRandom();
labelTop = new JLabel( "" );
//initialize with 3
for(int i = 0; i < 3; i++)
{
randomLetters += getRandomLetter();
}
labelTop.setText( randomLetters );
//...
add(labelTop, BorderLayout.NORTH);
}
also this block of code is not used at all because the condition is never met, since you initialize i to 0 and then say as long as it is less than 0:
for(int i = 0; i < 0; i++)
{
numberButtons[i] = new JButton();
numberButtonPanel.add(numberButtons[i]);
numberButtons[i].addActionListener(this);
}
EDIT:
since you added another part of the question, you asked why it is waiting an iteration before adding the character you just clicked in your actionPerformed method, and that is because you are setting the text before you add the next character to the string. So your actionPerformed method should look like:
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == red)
{
messageBottom += "R";
//System.out.println("R");
}
else if (e.getSource()==blue)
{
messageBottom += "B";
//System.out.println ("B");
}
else if (e.getSource()==yellow)
{
messageBottom += "Y";
//System.out.println ("Y");
}
else if (e.getSource()==green)
{
messageBottom += "G";
//System.out.println ("G");
}
labelBottom.setText (messageBottom);
}

Related

How to have two dependent actions within an ActionListener?

I'm trying to write a checkers AI program with a GUI in java. I've managed to initialise and fill the board so far (with pieces written as "B" and "W" for now). I've created a 2D JButton panel for the board.
I don't know how to proceed when moving pieces. My current issue is I need the player to select a preexisting piece (action 1) and then an empty space to place the selected piece (action 2). Of course these actions are dependent, and I need action 1 to happen first.
Here's what I've got so far:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class Checkers implements ActionListener{
private static final int BOARD_SIZE = 8;
Random random = new Random();
JFrame frame = new JFrame();
JPanel title_panel = new JPanel();
JPanel button_panel = new JPanel();
JLabel textfield = new JLabel();
JButton[][] buttons = new JButton[BOARD_SIZE][BOARD_SIZE];
Checkers(){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800,800);
frame.getContentPane().setBackground(new Color(50, 50, 50));
frame.setLayout(new BorderLayout());
frame.setVisible(true);
textfield.setBackground(new Color(25,25,25));
textfield.setForeground(new Color(25, 255, 0));
textfield.setFont(new Font("Arial", Font.BOLD, 75));
textfield.setHorizontalAlignment(JLabel.CENTER);
textfield.setText("Checkers");
textfield.setOpaque(true);
title_panel.setLayout(new BorderLayout());
title_panel.setBounds(0,0,800, 100);
button_panel.setLayout(new GridLayout(BOARD_SIZE,BOARD_SIZE));
button_panel.setBackground(new Color(150,150,150));
for (int i=0; i<BOARD_SIZE; i++){
for (int j=0; j<BOARD_SIZE; j++){
buttons[i][j] = new JButton();
button_panel.add(buttons[i][j]);
buttons[i][j].setFont(new Font("Arial",Font.BOLD, 30));
buttons[i][j].setFocusable(false);
buttons[i][j].addActionListener(this);
}
}
title_panel.add(textfield);
frame.add(title_panel, BorderLayout.NORTH);
frame.add(button_panel);
initialiseBoard(buttons);
}
#Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (e.getSource() == buttons[i][j]) {
String moving_piece = buttons[i][j].getText();
}
}
}
}
// method that fills the initial board.
public void initialiseBoard(JButton[][] buttons){
for (int i=0; i<BOARD_SIZE; i++){
for (int j=0; j<BOARD_SIZE; j++){
if (i<3){
if (i%2==0){
if (j%2 != 0){
buttons[i][j].setText("W");
}
}
else {
if (j%2==0){
buttons[i][j].setText("W");
}
}
}
if (i>=BOARD_SIZE-3){
if (i%2 == 0){
if (j%2 != 0){
buttons[i][j].setText("B");
}
}
else {
if (j%2==0){
buttons[i][j].setText("B");
}
}
}
}
}
}
}
As I mentioned in my comment, the key to a solution is to base your program's listener on "state-dependent behavior", meaning the behavior of the listener will depend on the state of the program.
For instance, if you give your program an instance field, say, selectedButton that held a reference to the last selected button, then any ActionListener's response can vary depending on what this field holds. The first time any JButton is pressed, this field will hold null since no previous JButton was pressed, and so the ActionListener will assign this button to that field. The second time that the ActionListener is called (the second time that a JButton is pressed), the field will hold a value, and so, using an if / else block that checks the state of this field, the listener's behavior can vary:
public class Checkers2 {
private static final int BOARD_SIZE = 8;
// .....
private JButton[][] buttons = new JButton[BOARD_SIZE][BOARD_SIZE];
private JButton selectedButton = null;
public Checkers2() {
buttonPanel.setLayout(new GridLayout(BOARD_SIZE, BOARD_SIZE));
for (int i = 0; i < buttons.length; i++) {
for (int j = 0; j < buttons[i].length; j++) {
buttons[i][j] = new JButton(" ");
buttonPanel.add(buttons[i][j]);
buttons[i][j].setFont(BTN_FONT);
buttons[i][j].setPreferredSize(BTN_SIZE);
buttons[i][j].addActionListener(e -> btnsActionPerormed(e));
}
}
// ...
}
private void btnsActionPerormed(ActionEvent e) {
JButton source = (JButton) e.getSource();
// if selectedButton is null, then this is the first press
if (selectedButton == null) {
if (source.getText().trim().isEmpty()) {
return; // no button text means that there is no piece here. Exit method
} else {
// first set the selectedButton's value
selectedButton = source;
// change its appearance so we know that it has been pressed
source.setForeground(Color.RED);
source.setBackground(Color.LIGHT_GRAY);
}
} else {
// else, if selectedButton is NOT null, then this is the second press
// only do things if this current button is empty, if it has no text
if (source.getText().trim().isEmpty()) {
selectedButton.setForeground(Color.BLACK);
selectedButton.setBackground(null);
source.setText(selectedButton.getText());
selectedButton.setText("");
// the code below is of key importance
selectedButton = null;
}
}
}
The last bit of code shown is also key -- with the second JButton press, we re-set selectedButton back to null, so that the program's state is set back to its initial state and so that the listener's initial behavior can repeat.
A simple example program that demonstrates this is as shown below. The program still has not encorporated true Checker's game logic where the program determines if a move is truly legal or not:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class Checkers2 {
private static final int BOARD_SIZE = 8;
private static final Font BTN_FONT = new Font("Arial", Font.BOLD, 30);
private static final Dimension BTN_SIZE = new Dimension(100, 100);
private JPanel buttonPanel = new JPanel();
private JButton[][] buttons = new JButton[BOARD_SIZE][BOARD_SIZE];
private JButton selectedButton = null;
public Checkers2() {
buttonPanel.setLayout(new GridLayout(BOARD_SIZE, BOARD_SIZE));
for (int i = 0; i < buttons.length; i++) {
for (int j = 0; j < buttons[i].length; j++) {
buttons[i][j] = new JButton(" ");
buttonPanel.add(buttons[i][j]);
buttons[i][j].setFont(BTN_FONT);
buttons[i][j].setPreferredSize(BTN_SIZE);
buttons[i][j].addActionListener(e -> btnsActionPerormed(e));
}
}
// Place "W" and "B" text in appropriate locations:
for (int i = 0; i < 12; i++) {
int wI = (2 * i) / BOARD_SIZE;
int wJ = (2 * i) % BOARD_SIZE + ((wI % 2 == 1) ? 0 : 1);
buttons[wI][wJ].setText("W");
buttons[BOARD_SIZE - wI - 1][BOARD_SIZE - wJ - 1].setText("B");
}
}
private void btnsActionPerormed(ActionEvent e) {
JButton source = (JButton) e.getSource();
// if selectedButton is null, then this is the first press
if (selectedButton == null) {
if (source.getText().trim().isEmpty()) {
return; // no button text means that there is no piece here. Exit method
} else {
// first set the selectedButton's value
selectedButton = source;
// change its appearance so we know that it has been pressed
source.setForeground(Color.RED);
source.setBackground(Color.LIGHT_GRAY);
}
} else {
// else, if selectedButton is NOT null, then this is the second press
// only do things if this current button is empty, if it has no text
if (source.getText().trim().isEmpty()) {
selectedButton.setForeground(Color.BLACK);
selectedButton.setBackground(null);
source.setText(selectedButton.getText());
selectedButton.setText("");
// the code below is of key importance
selectedButton = null;
}
}
}
public JPanel getButtonPanel() {
return buttonPanel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
Checkers2 checkers = new Checkers2();
JFrame frame = new JFrame("Checkers");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(checkers.getButtonPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
And I hope to show how to encorporate program logic in an edit. For this, I recommend using a "Model-View-Controller" or MVC program structure.
You need to memorize and manage the selection of a piece. You can do it by:
//Introduce a field to store selected button
private JButton selected = null ;
And modify the ActionListener:
#Override
public void actionPerformed(ActionEvent e) {
JButton clicked = (JButton) e.getSource();
if(selected != null ){
clicked.setText(selected.getText());
selected.setText("");
selected = null;
}else{
if( ! clicked.getText().isEmpty()) {
selected = clicked;
}
}
}
Consider using JToggleButtons instead of a JButtons .

How do I use IntBinaryOperator with a Switch Case Statement for Java Swing? (Simple Calculator)

I'm having trouble getting an output while using the switch-statement and IntBinaryOperator. I'm trying to build a simple calculator in Java, and I found that the IntBinaryOperator cut down on unnecessary boilerplate code. I hope that you can show me the best approach. Thank you.
The three classes that I wrote are below.
package gui_calc;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.function.IntBinaryOperator;
public class CalculatorJFrame extends JFrame implements ActionListener {
static protected JLabel lblOut;
private JButton btnEq;
private JButton btnClear;
public CalculatorJFrame() {
setTitle("CALCULATOR");
JPanel container = new JPanel(); //create a JPanel inside the JFrame as a container
container.setLayout(new BorderLayout());
//add your components in here
lblOut = new JLabel("");
btnEq = new JButton("=");
btnClear = new JButton("C");
btnEq.addActionListener(this);
btnClear.addActionListener(this);
NumButtonsJP numBtns = new NumButtonsJP(); //create an instance of NumButtonsJP
OpButtonsJP opBtns = new OpButtonsJP(); //create an instance of OpButtonsJP
container.add(btnClear, BorderLayout.WEST);
container.add(btnEq, BorderLayout.EAST);
container.add(lblOut, BorderLayout.NORTH);
container.add(numBtns, BorderLayout.CENTER); //add the numBtns JPanel to the container
container.add(opBtns, BorderLayout.SOUTH); //add the opBtns JPanel to the container
add(container); //add container to the JFrame
}
static protected void updateOutLabel(String suffix) {
String currLblContent = lblOut.getText().trim(); //get current content of lblOut
lblOut.setText(currLblContent + suffix); //update the output label on the main container
}
static protected void clearOutLabel() {
lblOut.setText("");
}
#Override
public void actionPerformed(ActionEvent e) {
String face = e.getActionCommand().trim();
switch (face) {
case "=":
//do math... get the values... and reset the label with the result
updateOutLabel("=" + getResultFromQuestion(lblOut.getText()));
break;
case "+":
IntBinaryOperator add = (a,b) -> a + b;
System.out.println("Your answer is" + (add));
break;
case "-":
IntBinaryOperator substract = (a, b) -> a - b;
System.out.println("Your answer is" + (substract.applyAsInt(lblOut.getText().charAt(0),lblOut.getText().charAt(1))));
break;
case "*":
IntBinaryOperator multiply = (a, b) -> a * b;
System.out.println("Your answer is" + (multiply));
break;
case "/":
IntBinaryOperator divide = (a, b) -> a / b;
System.out.println("Your answer is" + divide);
case "C":
clearOutLabel();
break;
}
}
private String getResultFromQuestion(String text) {
double resultStr = 10;
return "" + resultStr;
}
public static void main(String[] args) {
//create instance of calculator and run it
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
CalculatorJFrame calcGUI = new CalculatorJFrame();
calcGUI.setDefaultCloseOperation(calcGUI.EXIT_ON_CLOSE);
calcGUI.setSize(300, 300);
calcGUI.setVisible(true);
}
});
}
package gui_calc;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class OpButtonsJP extends JPanel implements ActionListener{
JButton btnAdd = new JButton("+");
JButton btnSub = new JButton("-");
JButton btnMul = new JButton("*");
JButton btnDiv = new JButton("/");
JButton [] opsBtns = {btnAdd, btnSub, btnMul, btnDiv};//array of jbuttons
public OpButtonsJP(){
setLayout(new GridLayout(1,4));
for(int i=0; i<opsBtns.length; i++){
add(opsBtns[i]); //add the button to the JPanel
opsBtns[i].addActionListener(this); //add the ActionListener to make the button functional
}
}
#Override
public void actionPerformed(ActionEvent e) {
String face = e.getActionCommand();
System.out.println(face + " was clicked");
CalculatorJFrame.updateOutLabel(face);
//String currLblContent = CalculatorJFrame.lblOut.getText();
//CalculatorJFrame.lblOut.setText(currLblContent + face); //update the output label on the main container
}
}
package gui_calc;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class NumButtonsJP extends JPanel implements ActionListener {
JButton numButtons[];
public NumButtonsJP() {
setLayout(new GridLayout(4, 3));
numButtons = new JButton[10];
for (int i = 1; i < 10; i++) {
//create a JButton with the number on its face and add it to the array of JButtons
numButtons[i] = new JButton("" + i);
numButtons[i].addActionListener(this); //make the button trigger the event
//add the JButton to the JPanel
add(numButtons[i]);
}
JLabel spaceHolder = new JLabel(); //create the spaceHolder as a blank label
add(spaceHolder); //add the spaceHolder to the JPanel
numButtons[0] = new JButton("0"); //create the Zero button
numButtons[0].addActionListener(this);//make the Zero button trigger actioNPerformed
add(numButtons[0]); //add the Zero button to the JPanel
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String face = e.getActionCommand();
System.out.println(face + " was clicked");
int num = Integer.parseInt(face.trim()); // parse to an int so we can use in math
CalculatorJFrame.updateOutLabel(face);
//String currLblContent = CalculatorJFrame.lblOut.getText();
//CalculatorJFrame.lblOut.setText(currLblContent + face); //update the output label on the main container
}
}
I change a little your code, basically I'm adding an evaluator of expressions.
The UI basically construct the expression and pass to your getResultFromQuestion() function which takes the input and then try to parse to a math function.
You must handle the exceptions properly, and it brokes your BinaryOperators since you could entry two of more operands.
#Override
public void actionPerformed(ActionEvent e) {
String face = e.getActionCommand().trim();
switch (face) {
case "=":
// do math... get the values... and reset the label with the result
updateOutLabel("=" + getResultFromQuestion(lblOut.getText()));
break;
case "C":
clearOutLabel();
break;
}
}
private String getResultFromQuestion(String text) {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = null;
try {
result = engine.eval(text);
} catch (ScriptException e) {
//Do something with the exception
}
return result.toString();
}

JButton method I cannot find

I'm working on a TicTacToe game at the moment as a personal project and so far I know I'm almost complete with the game except for the part where I have to check if the x or o's are equal and in a line. Here's my code below here. My problem is in the connected method, it compiles and run's, but when I tried to add the middle horizontal row after just only one JButton was pressed it said the person won which should not be the case. I think I need a method that is named isDisabled(), instead of isEnabled for the JButton, but for some reason I don't think there is such a method in the java library. I know for sure if I had isDisabled() it would work for sure
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Created by Usman on 5/17/2016.
*/
public class TicTacToeGUI extends JPanel {
boolean turn = true;
JButton[] board;
public TicTacToeGUI() {
setLayout(new GridLayout(3,3));
board = new JButton[9];
for (int i = 0; i < board.length; i++) {
board[i] = new JButton("");
board[i].setPreferredSize(new Dimension(70, 60));
board[i].setFont(new Font("Arial", Font.PLAIN, 40));
int finalI = i;
board[i].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(board[finalI].isEnabled()){
if(turn){
board[finalI].setText("X");
turn = !turn;
}
else{
board[finalI].setText("O");
turn = true;
}
board[finalI].setEnabled(false);
}
Connected();
}
});
add(board[i]);
}
}
public void Connected(){
int count =0;
//Horizontal top row
if((board[0].isEnabled() == board[1].isEnabled()) && (board[1].isEnabled() == board[2].isEnabled())){
System.out.println(count++);
for(int i = 0; i < board.length; i++)
board[i].setEnabled(false);
}
}
public static void main(String []args){
TicTacToeGUI game = new TicTacToeGUI();
JFrame frame = new JFrame("Tic Tac Toe");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(game);
frame.pack();
frame.setVisible(true);
}
}
Just use (!whatever.isEnabled())
The character '!' is similar to a NOT in Java. So it will behave like isDiabled()

How do I set my code so it allows the values "X" and "O" in the buttons?

I'm doing a tic tac toe board game. I already have the board in the window, but I don't know how to use the handler method to set the values in the buttons so the players can really play. This is what I have so far:
import javax.swing.*;
import java.awt.*;
public class TicTacToeGame implements java.awt.event.ActionListener {
private NscWindow win;
private JButton[][] button;
private boolean turnX;
private JLabel label;
public TicTacToeGame () {
win = new NscWindow(10,10, 235, 280);
win.setTitle("Tic-Tac-Toe");
javax.swing.JButton btn;
button = new JButton[3][3];
JButton[] buttons = new JButton[9];
for (int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
button[i][j] = new JButton();
button[i][j].setSize(50, 50);
button[i][j].setLocation(30 + i*55, 30+ j*55);
win.add(button[i][j]);
button[i][j].addActionListener(this);
win.repaint();
javax.swing.JLabel label;
label = new JLabel("X's turn", JLabel.CENTER);
label.setSize(160, 20);
label.setLocation(30, 200);
win.add(label);
win.repaint();
}
}
}
//Abstract method
public void actionPerformed(java.awt.event.ActionEvent e) {
javax.swing.JButton button;
button = (javax.swing.JButton)e.getSource();
button.setText("");
//count++;
// if(count %2 != 0) {
//letter = "X";
//}else{
//letter = "O";
//}
}
public static void main(String[] args) {
new TicTacToeGame();
}
}
The simple quick-fix: as noted in my comments, simply call setText(...) on your selected button after setting letter's value. You would first check the text to be sure that it isn't empty, something like:
// code not tested.
public void actionPerformed(java.awt.event.ActionEvent e) {
// get the button pressed
javax.swing.JButton button = (javax.swing.JButton)e.getSource();
// get the button's text
String text = button.getText();
// if the text either holds spaces or is empty
if (text.trim().isEmpty()) {
count++;
String letter = ""; // declare letter outside of the if/else block
// find out whose turn, and assign appropriate String to letter
if (count % 2 == 0) {
letter = "0";
} else {
letter = "X";
}
// use letter to set button's text
button.setText(letter);
}
}
The better over-all solution is to use an MVC like program structure such as can be found in this solution to a similar problem.

Random Tic-Tac-Toe image flipping

I have created a basic Tic-Tac-Toe class which displays 9 buttons showing random images on it(each run time - different sequences). The main method is there in another test class, which is just a frame creator. In addition to this, I want to add some event handling. I have added 'ActionListener' to the buttons & want to add some logic in 'actionPerformed' method. Each time I click on any button it should change an image continuously in order X -> O -> Blank -> X. I am not sure that which logic will fit here to flip images in above order(for e.g. for-loop,switch etc.). The code is as follows :
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TicTacToe extends JFrame {
public JButton[][] labels = new JButton[3][3];
public ImageIcon[] icons = new ImageIcon[3];
public int r, c;
public TicTacToe() {
// TODO Auto-generated constructor stub
setLayout(new GridLayout(3, 3));
for (r = 0; r < labels.length; r++) {
for (c = 0; c < labels.length; c++) {
int random = (int)(Math.random() * 3 + 0);
System.out.println(random);
JButton s = new JButton(this.icons[random]);
this.add(s);
this.labels[r][c] = s;
if (random == 0) {
System.out.println("Cross Image Icon");
labels[r][c].setIcon(new ImageIcon("C:\\Users\\yogesh\\workspace\\hw3pandarey\\src\\hw3pandarey\\cross_symbol.gif"));
add(labels[r][c]);
validate();
} else if (random == 1) {
System.out.println("Not Image Icon");
labels[r][c].setIcon(new ImageIcon("C:\\Users\\yogesh\\workspace\\hw3pandarey\\src\\hw3pandarey\\zero_symbol.gif"));
add(labels[r][c]);
validate();
} else if (random == 2) {
System.out.println("Keep it blank");
labels[r][c].setIcon(new ImageIcon());
add(labels[r][c]);
validate();
}
labels[r][c].addActionListener(new ButtonListener());
}
}
} // end of TicTacToe constructor
public class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
} // end of actionPerformed method
} // end of ButtonListener class
} // end of TicTacToe class
import javax.swing.*;
public class TicTacToeTest {
public static void main(String[] args) {
TicTacToe frame = new TicTacToe();
frame.setTitle("Let's play a random tic-tac-toe game !!!!!");
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
} //end of main method
} // end of test class
You can use the method setText to put an X or O on the JButton like so.
All you need to add if a variable that will know if it's X or O turn.
Hopefully this help
public class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
Object src = e.getSource();
for(int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if(src==labels[i][j]&&labels[i][j].getText()==""){
//if X turn
labels[i][j].setText("X");
}
//if O turn
//labels[i][j].setText("O");
}
}
}// end of actionPerformed method
} // end of ButtonListener class
So I added 'switch' inside 'for' loops, so that each time I click a button it flips an image in particular order. I wanted the same images to flip not any text, so I used 'setIcon()' method. For that I created three ImageIcon objects in main class.A counter is added for three different cases & it keeps looping.
My final answer code is as follows :
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TicTacToe extends JFrame
{
public JButton[][] labels = new JButton[3][3];
public ImageIcon[] icons = new ImageIcon[3];
byte value=0;
public ImageIcon x= new ImageIcon("C:\\Users\\yogesh\\workspace\\hw3pandarey\\src\\hw3pandarey\\cross_symbol.gif");
public ImageIcon o= new ImageIcon("C:\\Users\\yogesh\\workspace\\hw3pandarey\\src\\hw3pandarey\\zero_symbol.gif");
public ImageIcon n= new ImageIcon("");
public TicTacToe()
{
// TODO Auto-generated constructor stub
setLayout(new GridLayout(3,3));
for(int r=0; r<labels.length ; r++)
{
for(int c=0; c<labels.length ; c++)
{
int random = (int)(Math.random() * 3 + 0);
System.out.println(random);
JButton s = new JButton(this.icons[random]);
this.add(s);
this.labels[r][c] = s;
if(random == 0)
{
System.out.println("Cross Image Icon");
labels[r][c].setIcon(new ImageIcon("C:\\Users\\yogesh\\workspace\\hw3pandarey\\src\\hw3pandarey\\cross_symbol.gif"));
add(labels[r][c]);
validate();
}
else if(random == 1)
{
System.out.println("Not Image Icon");
labels[r][c].setIcon(new ImageIcon("C:\\Users\\yogesh\\workspace\\hw3pandarey\\src\\hw3pandarey\\zero_symbol.gif"));
add(labels[r][c]);
validate();
}
else if(random == 2)
{
System.out.println("Keep it blank");
labels[r][c].setIcon(new ImageIcon());
add(labels[r][c]);
validate();
}
labels[r][c].addActionListener(new ButtonListener());
}
}
} // end of TicTacToe constructor
public class ButtonListener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
for(int r = 0; r < 3; r++) {
for (int c = 0; c < 3; c++) {
if(e.getSource()==labels[r][c])
{
value++;
value%=3;
switch(value)
{
case 0:
labels[r][c].setIcon(n);
break;
case 1:
labels[r][c].setIcon(x);
break;
case 2:
labels[r][c].setIcon(o);
break;
} // end of switch
}// end of 'if'
} // end of inside for loop
} // end of outside for loop
} // end of actionPerformed method
} // end of ButtonListener class
} // end of TicTacToe class

Categories