Novice programmer here trying to make a tic tac toe GUI game. I'm stuck with my program though. I'm not sure how to place a check on hitting the same square twice. I was thinking an if statement inside my actionListener that said
if(button clicked = True)
{
JOptionPane.showMessageDialog((null, "ERROR", "Button already used.
Please hit again to change back", JOptionPane.ERROR_MESSAGE);
// STOP something along those lines
}
else
{
//Do nothing
}
would work but I can't get the program to work properly. I tried newTurn.getmodel().isPressed() and that didn't work and now with my current code the program outputs the error message after each move and the changes still appear on the board. Here's my code for this method. Any help is appreciated.
private class buttonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JButton newTurn = (JButton)e.getSource(); //get the particular button that was clicked
if(switchMove%2 == 0)
newTurn.setText("X");
else
newTurn.setText("O");
if(newTurn.isEnabled())
JOptionPane.showMessageDialog(null, "ERROR", "Button already used. Please hit again to change back", JOptionPane.ERROR_MESSAGE);
if(checkForWin() == true)
{
JOptionPane.showConfirmDialog(null, "Game Over.");
resetButtons();
}
switchMove++;
}
switch move is just an int set to 0 so evens are X and O's are odd. My if (newTurn.isEnabled()) is my issue
Here is my resolved code.
public void resetButtons()
{
for(int i = 0; i <= 8; i++)
{
buttons[i].setText("");
buttons[i].setEnabled(true);
}
}
private class buttonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JButton newTurn = (JButton)e.getSource();
if(switchMove%2 == 0)
newTurn.setText("X");
else
newTurn.setText("O");
if(newTurn.isEnabled())
newTurn.setEnabled(false);
if(checkForWin() == true)
{
JOptionPane.showConfirmDialog(null, "Game Over.");
resetButtons();
}
switchMove++;
}
In the actionPerformed() method I set the buttons to setEnabled(false) after a button was clicked. Then when a game is over the buttons that were previously disabled will be set to setEnabled(true) via the resetButtons method.
Related
Im trying to make a simple Tic Tac Toe game right now, i created a JFrame with the Grid Layout and added 9 buttons to it. Now uppon clicking one of those buttons i want to change the Icon of it to be either a cross or a circle, but it just doesnt do anything on click
#Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == this)
{
if (counter%2 == 0)
{
ImageIcon cross = new ImageIcon("Cross.png");
this.setIcon(cross);
}
if (counter%2 == 1)
{
ImageIcon circle = new ImageIcon("Circle.png");
this.setIcon(circle);
}
counter++;
}
}
Project Structure here
The actionPerformed method does work with a simple System.out.println() statement
Thanks in Advance!
You have to understand the meaning of e.getSource(), it's return all properties of button. Your condition e.getSource() == this return false that is a problem. You have to set image icon like new javax.swing.ImageIcon(getClass().getResource("path/img_name")).
Here down is generic code implementation so the logic will work on any of the nine buttons:
public void jButton1ActionPerformed(ActionEvent e)
{
JButton button = (JButton)e.getSource();
if(counter % 2 == 0)
{
button.setIcon(new javax.swing.ImageIcon(getClass().getResource("Cross.png")));
}
else
{
button.setIcon(new javax.swing.ImageIcon(getClass().getResource("Circle.png")));
}
counter++;
}
I am trying to do a simple Minesweeper game using JFrame, however I am having troubles with the creation of objects. I am creating 96 buttons, some of which get the property of being wrong ("F") and right ("R"):
public class GUIBase extends JFrame {
private JButton button;
private JButton fButton;
public GUIBase() {
super("Minesweeper");
setLayout(new FlowLayout());
//Fields
int position;
for (int i = 0; i < 96; i++) {
position = (int) (Math.random() * 100);
if (position < 80) {
button = new JButton("R");
button.setToolTipText("Is this the correct one?");
add(button);
} else {
fButton = new JButton("F");
fButton.setToolTipText("Is this the correct one?");
add(fButton);
}
}
I then use ActionListener in order to check whether or not the button is correct. If the button is correct, it will get .setEnabled(false), otherwise the game ends:
//Action
Action action = new Action();
button.addActionListener(action);
fButton.addActionListener(action);
}
private class Action implements ActionListener {
public void actionPerformed(ActionEvent event) {
System.out.println("Somethin");
if (event.getSource() == button) {
button.setEnabled(false);
} else if (event.getSource() == fButton) {
JOptionPane.showMessageDialog(null, "You lost!");
System.exit(0);
} else {
JOptionPane.showMessageDialog(null, "An error ocurred");
System.exit(0);
}
}
}
Everything in the game turns out as planned, however only the last correct button ("R") and last wrong one ("F") are connected to the ActionListener. The rest of the buttons do not do anything when pressed.
How can I fix this?
The problem is that you only have two variables (attributes of the class GUIBase, specifically), and your are assigning to it each time you create a new button. Hence, you only have a reference to the last buttons.
You need an array of buttons. Let's see:
public class GUIBase extends JFrame {
public final int MAX_BUTTONS = 96;
private JButton[] buttons;
// ...
}
The next step is to create the array itself at the beginning:
public GUIBase() {
super("Minesweeper");
setLayout(new FlowLayout());
this.buttons = new JButton[MAX_BUTTONS];
//Fields
int position;
for (int i = 0; i < buttons.length; i++) {
position = (int) (Math.random() * 100);
this.buttons[ i ] = new JButton("R");
this.buttons[ i ].setToolTipText("Is this the correct one?");
this.add(this.buttons[ i ]);
Action action = new Action();
this.buttons[ i ].addActionListener(action);
}
}
You'll probably need more depth in arrays in order to completely understand the code. Basically, an array is a continuous collection of variables, which you can index by its position, from 0 to n-1, being n the number of positions.
Then you'll probably be able to fill the gaps yourself.
Hope this helps.
One part of your problems is coming from your action listener.
Of course, one part is that your code probably needs a list/array to keep track of all created buttons; but at least right now, you can rework your code without using arrays/list:
private class Action implements ActionListener {
public void actionPerformed(ActionEvent event) {
System.out.println("Somethin");
if (event.getSource() instanceofJButton) {
JBUtton clickedButton = (JButton) event.getSource();
String buttonText = clickedButton.getText();
if (buttonText.equals("R") ...
else if (buttonText.equals("F")
You see, the whole point here is: as of now, you just need to know what kind of button was created. And your ActionListener knows which button it was clicked on ...
I am trying to make it easier to make buttons by making a method, but when i use the method to make a button nothing happens when i press the button, even though i have a listener for the button
public void assignButton(Button wtf,String text) //program to assign buttons easily
{
wtf = new Button(text);
add(wtf);
wtf.addActionListener(this);
}
i use assignButton(Check,"words"); to make the button
public void actionPerformed(ActionEvent event) //checks if button has been pressed
{
if(event.getSource() == Check)
{
code ++;
}
else
{
code = 2;
}
repaint();
every time i press the button it sets code to 2, anyone know what i am doing wrong?
Edit:
full code
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class PressSafeTemp extends Applet implements ActionListener
{
Button clear,Check;
int code = 0;
public void init() //assigns buttons
{
clear = new Button("C");
add(clear);
clear.addActionListener(this);
assignButton(Check,"words");
}
public void paint(Graphics g)
{
g.drawString(""+code,10,10);
}
public void assignButton(Button wtf,String text) //program to assign buttons easily
{
wtf = new Button(text);
add(wtf);
wtf.addActionListener(this);
}
public void actionPerformed(ActionEvent event) //checks if button has been pressed
{
if(event.getSource() == Check)
{
code ++;
}
else if(event.getSource() == clear)
{
code = 0;
}
else
{
code = 2;
}
repaint();
}
}
The problem is you pass Check to the method (as wtf) but then immediately set it to a new instance; this instance is not Check. It does get added but you can't get at it with Check.
You probably want to do...
Button getButton(String text) {
Button button = new Button(text);
button.addActionListener(this);
return button;
}
and then Check = getButton(someText); followed by add(Check);.
If you don't actually need Check laying around, you could also just add it directly with add(getButton(someText));.
I'm not sure what means for you event.getSource() == Check but that is the key, you need to check the correct comparison in your case. Something like for example:
event.getSource().class.equals(JCheckBox.class)
I have a JButton[][] array that stores every button on a grid.
What I want to do is :
1) click the jbutton(icon) that I want to move on the grid.
2) click on the jbutton that I want the previous selected jbutton(icon) to move to.
private class BListener implements MouseListener {
#Override
public void mouseClicked(MouseEvent e) {
JButton but = ((JButton) e.getSource());
if(iconSelected && !but.equals(selectedButton)){ // move(swap) buttons
but.setIcon(selectedButton.getIcon());
selectedButton.setBorder(BorderFactory.createLineBorder(Color.black));
selectedButton.setName(null);
selectedButton=but;
iconSelected=false;
}else if(!iconSelected && but.getName()!=null){
iconSelected=true;
selectedButton=but;
but.setBorder(BorderFactory.createLineBorder(Color.YELLOW,3));
}else{
if(iconSelected){
System.out.println("Already Selected");
}else{
System.out.println("Not selected");
}
}
}
I have tried some things that didnt work ( this moves the icon but the icon also remains at the starting location). Any insight would be helpfull.
That is because you never change the selectedButton's icon, Try this:
if(iconSelected && !but.equals(selectedButton)){ // move(swap) buttons
Icon bIcon = but.getIcon();
but.setIcon(selectedButton.getIcon());
selectedButton.setIcon(bIcon);
...
}
I am only 6 - 7 weeks into learning Java, so I apologize in advance if my code is sloppy or terminology is off. I'm trying to create program that creates a random number and allows the user to guess until they get the correct number. It serves no real purpose other than a learning experience for me.
I have the basic program working, I just want to add other elements to improve it and gain the experience.
The program runs in a JFrame and has a JTextField for the user to enter their guess. I have ActionListener setup for the JTextField. I'd like to add a Start button that displays at the beginning of the game. When the user clicks the start button, the JTextField should become active. Also, when the user clicks guesses the correct answer, I'd like to use the start button to reset the program. I've experimented with several ways to do this with no success. I believe this will require multiple ActionListeners in the same class. I'm not even sure if this is possible?
Here is my code. Thanks in advance for any help.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class JMyFrame2 extends JFrame implements ActionListener {
Random num = new Random();
int computerGenerated = num.nextInt(1000);
public int userSelection;
JTextField numberField = new JTextField(10);
JLabel label1 = new JLabel();
Container con = getContentPane();
int previousGuess;
// constructor for JMyFrame
public JMyFrame2(String title) {
super(title);
setSize(750, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
label1 = new JLabel(
"I have a number between 1 and 1000 can you guess my number?" + "Please enter a number for your first guess and then hit Enter.");
setLayout(new FlowLayout());
add(numberField);
add(label1);
System.out.println(computerGenerated);
numberField.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
userSelection = Integer.parseInt(numberField.getText());
con.setBackground(Color.red);
if (userSelection == computerGenerated) {
label1.setText("You are correct");
con.setBackground(Color.GREEN);
} else if (userSelection > computerGenerated) {
label1.setText("You are too high");
} else if (userSelection < computerGenerated) {
label1.setText("You are too low");
}
}
}
public class JavaProgram5 {
public static void main(String[] args) {
JMyFrame2 frame2 = new JMyFrame2("Assignment 5 - Number Guessing Game");
frame2.setVisible(true);
}
}
Sure you can have multiple action listeners.
In fact, your class should not implement it.
Start by removing the actionPerformed method,
and replace this line:
numberField.addActionListener(this);
With this:
numberField.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
userSelection = Integer.parseInt(numberField.getText());
con.setBackground(Color.red);
if (userSelection == computerGenerated) {
label1.setText("You are correct");
con.setBackground(Color.GREEN);
} else if (userSelection > computerGenerated) {
label1.setText("You are too high");
} else if (userSelection < computerGenerated) {
label1.setText("You are too low");
}
}
});
You can add another action listener to the start button you plan to add,
following this pattern, using an anonymous class.
(It doesn't have to be an anonymous class,
this was just simple to demonstrate.)
As janos said, adding an action listener to each button does the job well, but in large code when you need to add a lot of buttons it doesn't look too neat, I suggest you using the setActionCommand() for the JButtons that you are creating, the usage is simple, you implement ActionListener to the JFrame as you did but after each button add
button.addActionListener(this);
button.setActionCommand("commandname")
And you can do it for as much as buttons as you wish, now to fire these commands correctly your action performed function should look like this:
#Override
public void actionPerformed (ActionEvent e) {
String cmd = e.getActionCommand();
switch(cmd) {
case "action1":
// Do something
break;
case "action2":
// Do something else
break;
case "potato":
// Give Mr. chips a high five
break;
default:
// Handle other cases
break;
}
}
And so on, again the other solution works perfectly fine, I just personally think that this one is a lot neater especially in a code where you have multiple action listeners.