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++;
}
Related
I have built a snake game where a JPanel that implements a card layout manager is placed onto the JFrame. Three other JPanels are added to the card layout.
public void init () {
JOptionPane.showMessageDialog (this, "Don't let the snake hit the borders or you lose!", "Introduction to the Snake Game", JOptionPane.INFORMATION_MESSAGE);
appleCounter.label.setBorder (new LineBorder (Color.yellow, 1));
mainPanel.setLayout (card);//CHANGING THE LAYOUT MANAGER FOR THE JPANEL TO CARDLAYOUT
Screens [0] = new Screen ();//CREATING AN INSTANCE OF A JPANEL
mainPanel.add (Screens [0], "one");//ADDING THE JPANEL TO THE CARD LAYOUT
add (mainPanel, BorderLayout.CENTER);//ADDING THE JPANEL TO THE JFRAME
add (appleCounter.label, BorderLayout.SOUTH);
pack ();
setLocationRelativeTo (null);
setVisible (true);
}
This is so that after the snake collides with the border of the frame, a JDialog appears asking if they'd like to try again. If the player clicks 'yes' the next JPanel from the card layout will appear.
if (xCoor < 0 || xCoor > 80 || yCoor < 0 || yCoor > 60) {//IF THE SNAKE COLLIDES WITH THE BORDER OF THE FRAME
number = 1;
collide = true;
createApples ();
stop ();//CALLING THE METHOD THAT I AM HAVING PROBLEMS WITH
}
However, I am having issues with the stop method because when the snake collides with the border & the player clicks "yes" the next JPanel from the card layout appears. But the JPanel doesn't listen for any key inputs from the player, as a result, the snake cannot change directions.
public void stop () {
running = false;
try {
int response = JOptionPane.showConfirmDialog (this, "Do you want to play again?", "Opps looks like you lost", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (response == JOptionPane.YES_OPTION) {
if (digit < 3) {
Frame.card.removeLayoutComponent (Frame.Screens [digit]);
Frame.Screens [digit] = null;
digit++;
Frame.Screens [digit] = new Screen ();
if (digit == 1) {
Frame.card.removeLayoutComponent (Frame.Screens [digit]);
Frame.Screens [digit] = null;
Frame.mainPanel.add (Frame.Screens [digit], "two");
Frame.card.removeLayoutComponent (Frame.Screens [digit]);
} else if (digit == 2) {
Frame.mainPanel.add (Frame.Screens [digit], "three");
}
} else if (response == JOptionPane.NO_OPTION) {
System.exit (0);
} else if (response == JOptionPane.CLOSED_OPTION) {
System.exit (0);
}
thread.join ();
} catch (InterruptedException e) {
e.printStackTrace ();
}//CLOSE CATCH
}
The JPanel instances are created using the Screen class which extends from JPanel class, even though the two JPanels in the card layout setFocusable to true so it should throw keyEvents.
public Screen () {
setFocusable (true);//THE JPANEL COMPONENT WILL BE AN EVENT SOURCE, THROWING KEY EVENTS TO THE KEY INSTANCE
addKeyListener (new Key ());//REGISTER THE KEY INSTANCE TO LISTEN TO KEY EVENTS
setPreferredSize (new Dimension (WIDTH, HEIGHT));
r = new Random ();
apples = new ArrayList <Apple> ();
start ();
}
Here is the inner class which has the keyPressed () that is called when the player clicks a directional key:
public class Key implements KeyListener {
public void keyPressed (KeyEvent e) {
int key = e.getKeyCode ();
if (key == KeyEvent.VK_RIGHT && !left) {
up = false;
down = false;
right = true;
}
if (key == KeyEvent.VK_LEFT && !right) {
up = false;
down = false;
left = true;
}
if (key == KeyEvent.VK_UP && !down) {
left = false;
right = false;
up = true;
}
if (key == KeyEvent.VK_DOWN && !up) {
left = false;
right = false;
down = true;
}
}
public void keyReleased (KeyEvent e) {}
public void keyTyped (KeyEvent e) {}
I am a beginner at Java so I would appreciate it if when answering this question there is a minimal amount of technical language or that the answer is explained in a way a beginner can understand. To clarify only the first Screen instance created in the init () listens for key inputs, the other two Screen instances cannot.
I need to start off with a JLabel, for example a JLabel that reads,"Old Text". With a button click, I want to update that JLabel to, "Updated Text". I am able to do this with the code I posted below, but my issue is I want to be able to click the button again to go back to "Old Text" and so on. Basically, I need the button to allow me to alternate between those two texts but I can't get that to work.
// this doesn't switch back to "Old Code"
public void actionPerformed(ActionEvent event) {
if(event.getSource() == jbutton)
jlabel.setText("Updated Text");
if(event.getSource() == jbutton)
jlabel.setText("Old Text");
}
This works but isn't what I fully need because it only changes the JLabel once.
public void actionPerformed(ActionEvent event) {
if(event.getSource() == jbutton)
jlabel.setText("Updated Text");
}
The reason your code isn't work is, both if statements evaluate to true, so both get executed
There are several ways you might do this, probably the simplest is just to inspect the state of the text of the label and make some decision about what to do, for example...
public void actionPerformed(ActionEvent event) { if(event.getSource() == jbutton) jlabel.setText("Updated Text");
if(event.getSource() == jbutton) {
if (!jlabel.getText().equals("Old Text")) {
jlabel.setText("Old Text");
} else {
jlabel.setText("Updated text");
}
}
}
Now, if you wanted to be "really" fancy, you could use a little bit of modular maths...
private int trigger = 0;
#Override
public void actionPerformed(ActionEvent e) {
trigger++;
if ((trigger % 2) == 0) {
label.setText("Old text");
} else {
label.setText("Updated text");
}
}
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.
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);
...
}