I have a GUI created in my main class file
import java.awt.*;
import javax.swing.*;
public class TicTac extends JFrame {
TicTacEvent tictac = new TicTacEvent(this);
JPanel row1 = new JPanel();
JButton[][] boxes = new JButton[4][4];
JButton play = new JButton("Play");
JButton restart = new JButton("Restart");
JTextField blank1 = new JTextField();
JTextField blank2 = new JTextField();
JOptionPane win = new JOptionPane("Winner");
ImageIcon back = new ImageIcon("cardback.jpg");
public TicTac() {
super ("Tic Tac Toe");
setSize (800,650);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FlowLayout layout = new FlowLayout();
setLayout(layout);
int name = 0;
String newname;
GridLayout layout1 = new GridLayout(5, 4, 10, 10);
row1.setLayout(layout1);
for (int x=0; x<=3; x++){
for (int y=0; y<=3; y++){
name = name + 1;
newname = Integer.toString(name);
boxes[x][y] = new JButton(newname);
boxes[x][y].setIcon(back);
row1.add(boxes[x][y]);
}
}
row1.add(blank1);
row1.add(play);
row1.add(blank2);
row1.add(restart);
add (row1);
play.addActionListener(tictac);
for (int x=0; x<=3; x++){
for (int y=0; y<=3; y++){
boxes[x][y].addActionListener(tictac);
}
}
setVisible(true);
}
public static void main(String[] arguments){
TicTac frame = new TicTac();
}
}
And I have code using it here
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class TicTacEvent implements ItemListener, ActionListener, Runnable {
TicTac gui;
Thread playing;
Thread restarting;
ImageIcon a = new ImageIcon("x.jpg");
ImageIcon b = new ImageIcon("o.jpg");
int clicks = 0;
int win = 0;
int winx = 0;
int winy = 0;
int cat = 0;
int[][] check = new int[4][4];
public TicTacEvent (TicTac in){
gui = in;
for (int row=0; row<=3; row++){
for (int col=0; col<=3; col++){
check[row][col]=0;
}
}
}
public void actionPerformed(ActionEvent event){
String command = event.getActionCommand();
if (command.equals("Play")) {
startPlaying();
} else if (command.equals("Restart")) {
restart();
}
if (command.equals("1")) {
b1();
}
if (command.equals("2")) {
b2();
}
if (command.equals("3")) {
b3();
}
if (command.equals("4")) {
b4();
}
if (command.equals("5")) {
b5();
}
if (command.equals("6")) {
b6();
}
if (command.equals("7")) {
b7();
}
if (command.equals("8")) {
b8();
}
if (command.equals("9")) {
b9();
}
if (command.equals("10")) {
b10();
}
if (command.equals("11")) {
b11();
}
if (command.equals("12")) {
b12();
}
if (command.equals("13")) {
b13();
}
if (command.equals("14")) {
b14();
}
if (command.equals("15")) {
b15();
}
if (command.equals("16")) {
b16();
}
gui.blank1.setText("X Wins: " + winx + " Y Wins:" + winy);
gui.blank2.setText("Cat Wins(Tie):" + cat);
}
void b1() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[0][0].setIcon(a);
check[0][0] = 1;
} else {
gui.boxes[0][0].setIcon(b);
check[0][0] = 2;
}
winner();
}
void b2() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[0][1].setIcon(a);
check[0][1] = 1;
} else {
gui.boxes[0][1].setIcon(b);
check[0][1] = 2;
}
winner();
}
void b3() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[0][2].setIcon(a);
check[0][2] = 1;
} else {
gui.boxes[0][2].setIcon(b);
check[0][2] = 2;
}
winner();
}
void b4() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[0][3].setIcon(a);
check[0][3] = 1;
} else {
gui.boxes[0][3].setIcon(b);
check[0][3] = 2;
}
winner();
}
void b5() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[1][0].setIcon(a);
check[1][0] = 1;
} else {
gui.boxes[1][0].setIcon(b);
check[1][0] = 2;
}
winner();
}
void b6() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[1][1].setIcon(a);
check[1][1] = 1;
} else {
gui.boxes[1][1].setIcon(b);
check[1][1] = 2;
}
winner();
}
void b7() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[1][2].setIcon(a);
check[1][2] = 1;
} else {
gui.boxes[1][2].setIcon(b);
check[1][2] = 2;
}
winner();
}
void b8() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[1][3].setIcon(a);
check[1][3] = 1;
} else {
gui.boxes[1][3].setIcon(b);
check[1][3] = 2;
}
winner();
}
void b9() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[2][0].setIcon(a);
check[2][0] = 1;
} else {
gui.boxes[2][0].setIcon(b);
check[2][0] = 2;
}
winner();
}
void b10() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[2][1].setIcon(a);
check[2][1] = 1;
} else {
gui.boxes[2][1].setIcon(b);
check[2][1] = 2;
}
winner();
}
void b11() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[2][2].setIcon(a);
check[2][2] = 1;
} else {
gui.boxes[2][2].setIcon(b);
check[2][2] = 2;
}
winner();
}
void b12() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[2][3].setIcon(a);
check[2][3] = 1;
} else {
gui.boxes[2][3].setIcon(b);
check[2][3] = 2;
}
winner();
}
void b13() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[3][0].setIcon(a);
check[3][0] = 1;
} else {
gui.boxes[3][0].setIcon(b);
check[3][0] = 2;
}
winner();
}
void b14() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[3][1].setIcon(a);
check[3][1] = 1;
} else {
gui.boxes[3][1].setIcon(b);
check[3][1] = 2;
}
winner();
}
void b15() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[3][2].setIcon(a);
check[3][2] = 1;
} else {
gui.boxes[3][2].setIcon(b);
check[3][2] = 2;
}
winner();
}
void b16() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[3][3].setIcon(a);
check[3][3] = 1;
} else {
gui.boxes[3][3].setIcon(b);
check[3][3] = 2;
}
winner();
}
public void winner() {
/** Check rows for winner */
for (int x=0; x<=3; x++){
if ((check[x][0]==check[x][1])&&(check[x][0]==check[x][2]) && (check[x][0]== check[x][3])) {
if (check[x][0] ==1) {
JOptionPane.showMessageDialog(null, "X is the winner");
win = 1;
winx +=1;
} else if (check[x][0]==2){
JOptionPane.showMessageDialog(null, "Y is the winner");
win = 1;
winy +=1;
}
}
}
/** Check columns for winner */
for (int x=0; x<=3; x++){
if ((check[0][x]==check[1][x])&&(check[0][x]==check[2][x])&& (check[0][x]== check[3][x])) {
if (check[0][x]==1) {
JOptionPane.showMessageDialog(null, "X is the winner");
win = 1;
winx +=1;
} else if (check[0][x]==2) {
JOptionPane.showMessageDialog(null, "Y is the winner");
win = 1;
winy +=1;
}
}
}
if ((check[1][1]== 1) && (check[3][3] == 1) && (check[2][2]==1) && (check[0][0]==1)
|| (check[3][0]==1) &&(check[1][2]==1) &&(check[0][3]==1))
{
JOptionPane.showMessageDialog(null, "X is the winner");
win = 1;
winx +=1;
} else if ((check[1][1]== 2) && (check[3][3] == 2) && (check[2][2]==2) && (check[0][0]==2)
|| (check[3][0]==2) &&(check[1][2]==2) &&(check[0][3]==2)) {
JOptionPane.showMessageDialog(null, "Y is the winner");
win = 1;
winy +=1;
}
//}
/** Checks if the game is a tie */
if ((clicks==16) && (win==0)) {
JOptionPane.showMessageDialog(null, "The game is a tie");
cat =+1;
}
}
public void startPlaying() {
playing = new Thread(this);
playing.start();
gui.play.setEnabled(false);
}
public void restart() {
TicTac restartok = new TicTac();
restartok.row1.add(restartok.blank1);
restartok.row1.add(restartok.play);
restartok.row1.add(restartok.blank2);
restartok.row1.add(restartok.restart);
restartok.add (restartok.row1);
restartok.play.addActionListener(restartok.tictac);
for (int x=0; x<=3; x++){
for (int y=0; y<=3; y++){
restartok.boxes[x][y].addActionListener(restartok.tictac);
}
}
}
public void itemStateChanged(ItemEvent e) {
// throw new UnsupportedOperationException("Not supported yet.");
}
public void run() {
//restart();
//throw new UnsupportedOperationException("Not supported yet.");
}
}
However my question is how I'd reset the GUI, I have some ideas..
The constructor "Public TicTac" creates the gui, however I am not sure how I'd get to happen again through another classfile. My understanding of OOP is that with a constructor I can call to by creating an object
TicTac restartok = new TicTac();
So assumedly, you'd think I'd be creating another JPanel/GUI everytime I called the restart(); method, no?
My OOP expeirence is limited, so I don't have a clue where to start or find out what logic is incorrect. Thanks.
To reset the game, just reset clicks to 0 and the buttons to their original state just as they were created:
boxes[x][y] = new JButton(newname);
boxes[x][y].setIcon(back);
Apart from that, you have many things to fix in your code. Here are some:
Your line boxes[x][y].addActionListener(tictac); is in a loop of its own where it should be in the initial loop. No reason to iterate twice over the same arrays.
Your layout decisions could be better (depending on what exactly you want to get).
Start the GUI with TicTac frame = new TicTac(); from inside an invokeLater method.
Create an ActionListener for each button with a unique functionality. In your case it's 1 for play, 1 for restart, and 1 for all the board buttons.
You're using event.getActionCommand but you did not call setActionCommand on any of the buttons.
Don't use multiple if when you check for the button pressed (action command name), use if else, or better - use a switch statement.
Don't use a separate function for each button. Use 1 function which receives the button as its argument.
Don't create fields when you can create local variables instead.
If you need clarifications leave a comment.
Edit: here is some modified code that resets the buttons (I couldn't stop myself from correcting other parts of the code, though there is still more to do).
public class TicTac extends JFrame {
static JButton[][] boxes = new JButton[4][4];
static int[][] check = new int[4][4];
static JTextField blank1 = new JTextField();
static JTextField blank2 = new JTextField();
static int turns = 1;
static ImageIcon back = new ImageIcon("cardback.jpg");
static ImageIcon x = new ImageIcon("x.jpg");
static ImageIcon o = new ImageIcon("o.jpg");
public TicTac() {
JPanel gamePanel = new JPanel(new GridLayout(5, 4, 10, 10));
for (int x = 0; x<=3; x++) {
for (int y = 0; y<=3; y++) {
boxes[x][y] = new JButton(""+x+y, back);
boxes[x][y].addActionListener(new XOActionListenr(x, y));
gamePanel.add(boxes[x][y]);
}
}
JButton play = new JButton("Play");
JButton restart = new JButton("Restart");
play.addActionListener(new PlayActionListenr());
restart.addActionListener(new RestartActionListenr());
setLayout(new FlowLayout());
gamePanel.add(blank1);
gamePanel.add(play);
gamePanel.add(blank2);
gamePanel.add(restart);
add(gamePanel);
setTitle("Tic Tac Toe");
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
private void winner() {
// Check for winner
}
private class XOActionListenr implements ActionListener {
private int row, col;
private XOActionListenr(int row, int col) {
this.row = row;
this.col = col;
}
public void actionPerformed(ActionEvent e) {
if (turns % 2 == 0) {
boxes[row][col].setText("O");
boxes[row][col].setIcon(o);
check[row][col] = 2;
}
else {
boxes[row][col].setText("X");
boxes[row][col].setIcon(x);
check[row][col] = 1;
}
winner();
turns++;
}
}
private class PlayActionListenr implements ActionListener {
public void actionPerformed(ActionEvent e) {
// Not sure why you would need the "play" button at all,
// but insert here what it's supposed to do
}
}
private class RestartActionListenr implements ActionListener {
public void actionPerformed(ActionEvent e) {
for (int x = 0; x<=3; x++) {
for (int y = 0; y<=3; y++) {
boxes[x][y].setText(""+x+y);
boxes[x][y].setIcon(back);
}
}
}
}
public static void main(String[] arguments) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TicTac();
}
});
}
}
You do not need to re-create whole GUI again and again. what you need to do is to clear textfields and whatever selection user has made till now. So you need to create a separate method in which you will reset the state of every button/textfields in your GUI.
for example: to clear textfield you will call setText("") method.
Hope this helps.
Related
I am making a basic platformer game and I need to make it so that every time you jump all the platforms that are below where you jumped disappear and every platform above moves down. It is still in development so just ignore some of the things that are commented out and the messy mode.
Basically, my problem is that when I try to clear all the platforms below the one that you clicked it works fine using this code:
for(int i = 0; i < platforms.length; i++) {
if(platforms[i] == null) {
continue;
}
if(parameters[i][1] > y) {
platforms[i].setVisible(false);
}
}
However later when I try to use .setvisible(true) on the platform that you clicked it doesn't work. Here is the full code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.math.*;
import java.util.*;
public class Main implements ActionListener {
static JFrame frame;
static JPanel panel;
//static JLabel title;
//static JLabel expl;
static JButton[] platforms;
static Random random;
static boolean playing;
static int[][] parameters;
static int platformsMade;
static int clicked;
static int preClicked;
static int score;
static int lives;
static int standing;
static int speed;
static double gravity;
static int jump;
static String action;
public Main(int seed) throws Exception {
frame = new JFrame("Snakes 'n' Adders");
panel = new JPanel(null);
//title = new JLabel("Snakes 'n' Adders", SwingConstants.CENTER);
//expl = new JLabel("");
platforms = new JButton[100000];
random = new Random();
parameters = new int[100000][5];
lives = 3;
speed = 10;
gravity = 9.81;
jump = 5;
action = "";
//panel.add(title);
//panel.add(expl);
frame.add(panel);
panel.setVisible(true);
frame.setVisible(true);
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
random.setSeed(seed);
panel.setBackground(Color.CYAN);
//title.setFont(new Font("Arial", Font.PLAIN, 50));
}
public void drawPlatform(int x, int y, int w, int h, int colour) {
platforms[platformsMade] = new JButton();
platforms[platformsMade].addActionListener(this);
platforms[platformsMade].setBounds(x, y, w, h);
switch(colour) {
case 0:
platforms[platformsMade].setBackground(Color.BLUE);
break;
case 1:
platforms[platformsMade].setBackground(Color.GREEN);
break;
case 2:
platforms[platformsMade].setBackground(Color.RED);
break;
case 3:
platforms[platformsMade].setBackground(Color.ORANGE);
break;
case 4:
platforms[platformsMade].setBackground(Color.GRAY);
break;
}
parameters[platformsMade][0] = x;
parameters[platformsMade][1] = y;
parameters[platformsMade][2] = w;
parameters[platformsMade][3] = h;
parameters[platformsMade][4] = colour;
panel.add(platforms[platformsMade]);
platforms[platformsMade].setVisible(true);
panel.repaint();
platformsMade++;
}
public void movePlatforms(int distance, int i) {
if(platforms[i] == null) {
NullPointerException end = new NullPointerException();
throw end;
}
//this.drawPlatform(parameters[i][0], parameters[i][1] + distance, parameters[i][2], parameters[i][3], parameters[i][4]);
//platforms[i].setVisible(false);
platforms[i].setBounds(parameters[i][0], parameters[i][1] + distance, parameters[i][2], parameters[i][3]);
parameters[i][1] = parameters[i][1] + distance;
}
#Override
public void actionPerformed(ActionEvent event) {
preClicked = clicked;
for(int i = 0; i < platforms.length; i++) {
if(event.getSource() == platforms[i]) {
clicked = i;
break;
}
}
int y = parameters[clicked][1];
for(int i = 0; i < platforms.length; i++) {
if(platforms[i] == null) {
continue;
}
if(parameters[i][1] > y) {
platforms[i].setVisible(false);
}
else {
this.movePlatforms(150, i);
}
this.movePlatforms(150, clicked);
}
for(int i = 0; i <= random.nextInt(2); i++) {
this.drawPlatform(random.nextInt(500), random.nextInt(500), 50, 50, random.nextInt(4));
}
/*for(int i = 0; i < platforms.length; i++) {
if(platforms[i] == null) {
continue;
}
if(platforms[i].getY() > frame.getY() - platforms[i].getHeight()) {
platforms[i].setVisible(false);
}
}*/
platforms[clicked].addActionListener(this);
platforms[clicked].setVisible(true);
standing = clicked;
for(int i = 0; i < platforms.length; i++) {
if(platforms[i] == null) {
continue;
}
if(clicked == i) {
platforms[i].setText("|");
}
else {
platforms[i].setText("");
}
}
}
public static void main(String[] args) throws Exception {
Main sna = new Main(7845);
//title.setVisible(true);
//expl.setVisible(false);
//Thread.sleep(5000);
//title.setVisible(false);
//expl.setVisible(true);
//Thread.sleep(40000);
for(int i = 0; i < 3; i++) {
sna.drawPlatform(random.nextInt(500), random.nextInt(500), 50, 50, random.nextInt(4));
}
int ticks = 0;
platforms[standing].setText("|");
}
}
I'm new to Java and trying to make a simple Player vs. Computer "Tic-Tac-Toe" game using Swing. In the code I use paintComponent() method to paint certain components and call the repaint() method after the player or computer plays. The problem is that, the game freezes after the third (sometimes the second) time I click the mouse. In GameWindow class I create the instance of Map class.
public class GameWindow extends JFrame{
private final int sizeX = 3;
private final int sizeY = 3;
public GameWindow(){
setLocation(400,150);
setSize(406, 452);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setResizable(false);
Map map = new Map(sizeX, sizeY);
add(map, BorderLayout.CENTER);
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new GridLayout(1, 2));
add(bottomPanel, BorderLayout.SOUTH);
Button newGame = new Button("Новая игра");
newGame.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Начинаем новую игру");
}
});
Button exit = new Button("Выход");
exit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
bottomPanel.add(newGame);
bottomPanel.add(exit);
setVisible(true);
}
}
Here is the listener for the mouse click in the Map class:
public class Map extends JPanel {
private final int sizeX;
private final int sizeY;
private int cellWidth;
private int cellHeight;
private int cellX = -1;
private int cellY = -1;
private String lastPlayer = "nobody";
private String[][] table = new String[3][3];
public Map(int sizeX, int sizeY) {
this.sizeX = sizeX;
this.sizeY = sizeY;
setBackground(Color.WHITE);
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table.length; j++) {
table[i][j] = "empty";
}
}
addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
super.mouseReleased(e);
cellX = e.getX() / cellWidth;
cellY = e.getY() / cellHeight;
if (!winOrDraw()) {
boolean playerProgress = playerProgress();
if(playerProgress) {
botProgress();
}
}
}
});
}
Both in playerProgress() and botProgress() methods I call repaint() method to add new components to the screen. I can't really find out what is the problem in this code and why the program freezes after actually 6th call of repaint() method?
Here are winOrDraw(), playerProgress() and botProgress() methods:
private boolean winOrDraw(){
for (int i = 0; i < table.length; i++) {
if(table[i][0] == table[i][1] && table[i][1] == table[i][2] && !table[i][0].equals("empty")) return true;
else if(table[0][i] == table[1][i] && table[1][i] == table[2][i] && !table[0][i].equals("empty")) return true;
else if(table[0][0] == table[1][1] && table[1][1] == table[2][2] && !table[0][0].equals("empty")) return true;
else if(table[2][0] == table[1][1] && table[1][1] == table[0][2] && !table[2][0].equals("empty")) return true;
}
int i, j = 0;
for (i = 0; i < table.length; i++) {
for (j = 0; j < table.length; j++) {
if(table[i][j].equals("empty")) break;
}
}
if(i == table.length && j == table.length) { lastPlayer = "nobody"; return true; }
else return false;
}
private boolean playerProgress(){
if(!table[cellY][cellX].equals("empty")){
System.out.println("This cell is not empty");
return false;
} else {
lastPlayer = table[cellY][cellX] = "player";
repaint();
return true;
}
}
private void botProgress(){
do{
if(winOrDraw()){
switch (lastPlayer) {
case "player":
System.out.println("You won!");
System.exit(0);
case "bot":
System.out.println("Bot won");
System.exit(0);
default:
System.out.println("Draw");
System.exit(0);
}
}
Random random = new Random();
cellX = random.nextInt(2);
cellY = random.nextInt(2);
if(table[cellY][cellX].equals("empty")) {
lastPlayer = table[cellY][cellX] = "bot";
break;
}
}while (!table[cellY][cellX].equals("empty"));
System.out.println("Bot's turn");
repaint();
}
You are adding your Swing components directly to the JFrame-AWT-container. You should not do that. Instead you should do this:
JPanel panel = new JPanel();
myFrame.setContentPane(panel);
panel.setLayout(...)
panel.add(...);
panel.validate();
This should solve your problem.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class Tix extends JFrame {
private static final int WIDTH = 500;
private static final int HEIGHT = 500;
private boolean xTurn = true;
private Font style;
private static JButton[][] btns = new JButton[3][3];
public Tix() {
setTitle("Tix");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(WIDTH, HEIGHT);
createContents();
setVisible(true);
}
public void createContents() {
style = new Font("Comic Sans", 1, 100);
Listener listener = new Listener();
setLayout(new GridLayout(3,3));
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
btns[i][j] = new JButton();
btns[i][j].setFont(style);
btns[i][j].addActionListener(listener);
add(btns[i][j]);
}
}
}
private class Listener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton btn = (JButton) e.getSource();
if (xTurn)
btn.setForeground(Color.RED);
else
btn.setForeground(Color.BLUE);
if (btn.getText().isEmpty()) {
btn.setText(xTurn ? "X" : "O");
if (win()) {
JOptionPane.showMessageDialog(null, "Congratulations! Player " + (xTurn ? "X" : "O") + " wins!");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
btns[i][j].setText(null);
}
}
xTurn = true;
}
else {
xTurn = !xTurn;
}
}
else {
JOptionPane.showMessageDialog(null,"Cell already clicked!");
}
}
}
public static boolean win() {
for (int i = 0; i < 3; i++)
if (btns[i][0].equals("X") && btns[i][1].equals("X") && btns[i][2].equals("X"))
return true;
for (int j = 0; j < 3; j++)
if (btns[0][j].equals("X") && btns[1][j].equals("X") && btns[2][j].equals("X"))
return true;
if (btns[0][0].equals("X") && btns[1][1].equals("X") && btns[2][2].equals("X"))
return true;
if (btns[0][2].equals("X") && btns[1][1].equals("X") && btns[2][0].equals("X"))
return true;
return false;
}
public static void main(String[] args) {
new Tix();
}
}
A for loop to check for the rows.
A for loop to check for the columns.
Two if statements to check for diagonals.
The win method does not return true at all. Is there something wrong with the && operators?
btns[i][j] is a JButton so it will never be equal to a String.
You should replace each method call of the form btns[i][0].equals("X") with something like btns[i][0].getText().equals("X").
Beside that, your win method only checks if the "X" player won. What about the "O" player?
public static void main(String[] arguments){
TicTac frame = new TicTac();
}
The second TicTac says cannot find symbol and asks to create constructor TicTac();.
My constructer is as follows:
public TicTac(TicTac in) {
}
I have tried
TicTac frame = new TicTac(TicTac in);
Here is the whole code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.*;
import tictactoe.TicTac;
public class TicTac extends JFrame implements ItemListener, ActionListener, Runnable{
TicTac gui;
Thread playing;
TicTacEvent tictac = new TicTacEvent(this);
JPanel row1 = new JPanel();
JButton[][] boxes = new JButton[3][3];
JButton play = new JButton("Play");
JTextField blank1 = new JTextField();
JTextField blank2 = new JTextField();
JOptionPane win = new JOptionPane("Winner");
ImageIcon back = new ImageIcon("cardback.jpg");
ImageIcon a = new ImageIcon("x.jpg");
ImageIcon b = new ImageIcon("o.jpg");
int clicks = 0;
//int win = 0;
int winX = 0;
int winO = 0;
int tie = 0;
int[][] check = new int[3][3];
public TicTac(TicTac in) {
super ("Tic Tac Toe");
gui = in;
setSize (500,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FlowLayout layout = new FlowLayout();
setLayout(layout);
int name = 0;
String newname;
for (int row=0; row<=2;row++){
for(int col=0; col<=2; col++){
check[row][col]=0;
}
}
GridLayout layout1 = new GridLayout(4, 3, 10, 10);
row1.setLayout(layout1);
for (int x=0; x<=2; x++){
for (int y=0; y<=2; y++){
name = name + 1;
newname = Integer.toString(name);
boxes[x][y] = new JButton(newname);
boxes[x][y].setIcon(back);
row1.add(boxes[x][y]);
}
}
row1.add(blank1);
row1.add(play);
row1.add(blank2);
add (row1);
play.addActionListener(tictac);
for (int x=0; x<=2; x++){
for (int y=0; y<=2; y++){
boxes[x][y].addActionListener(tictac);
}
}
setVisible(true);
}
public static void main(String[] arguments){
TicTac frame = new TicTac();
}
public void itemStateChanged(ItemEvent ie) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void actionPerformed(ActionEvent event) {
String command = event.getActionCommand();
if (command.equals("Play")) {
startPlaying();
}
if (command.equals("1")) {
b1();
}
if (command.equals("2")) {
b2();
}
if (command.equals("3")) {
b3();
}
if (command.equals("4")) {
b4();
}
if (command.equals("5")) {
b5();
}
if (command.equals("6")) {
b6();
}
if (command.equals("7")) {
b7();
}
if (command.equals("8")) {
b8();
}
if (command.equals("9")) {
b9();
}
}
void b1() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[0][0].setIcon(a);
check[0][0] = 1;
} else {
gui.boxes[0][0].setIcon(b);
check[0][0] = 2;
}
winner();
}
void b2() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[0][1].setIcon(a);
check[0][1] = 1;
} else {
gui.boxes[0][1].setIcon(b);
check[0][1] = 2;
}
winner();
}
void b3() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[0][2].setIcon(a);
check[0][2] = 1;
} else {
gui.boxes[0][2].setIcon(b);
check[0][2] = 2;
}
winner();
}
void b4() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[1][0].setIcon(a);
check[1][0] = 1;
} else {
gui.boxes[1][0].setIcon(b);
check[1][0] = 2;
}
winner();
}
void b5() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[1][1].setIcon(a);
check[1][1] = 1;
} else {
gui.boxes[1][1].setIcon(b);
check[1][1] = 2;
}
winner();
}
void b6() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[1][2].setIcon(a);
check[1][2] = 1;
} else {
gui.boxes[1][2].setIcon(b);
check[1][2] = 2;
}
winner();
}
void b7() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[2][0].setIcon(a);
check[2][0] = 1;
} else {
gui.boxes[2][0].setIcon(b);
check[2][0] = 2;
}
winner();
}
void b8() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[2][1].setIcon(a);
check[2][1] = 1;
} else {
gui.boxes[2][1].setIcon(b);
check[2][1] = 2;
}
winner();
}
void b9() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[2][2].setIcon(a);
check[2][2] = 1;
} else {
gui.boxes[2][2].setIcon(b);
check[2][2] = 2;
}
winner();
}
void winner() {
/** Check rows for winner */
for (int x=0; x<=2; x++){
if ((check[x][0]==check[x][1])&&(check[x][0]==check[x][2])) {
if (check[x][0]==1) {
JOptionPane.showMessageDialog(null, "X is the winner");
winX = 1;
System.out.println(Integer.toString(winX));
blank1.setText("Number of X Wins = " + (Integer.toString(winX)));
} else if (check[x][0]==2){
JOptionPane.showMessageDialog(null, "O is the winner");
winO = 1;
}
}
}
/** Check columns for winner */
for (int x=0; x<=2; x++){
if ((check[0][x]==check[1][x])&&(check[0][x]==check[2][x])) {
if (check[0][x]==1) {
JOptionPane.showMessageDialog(null, "X is the winner");
winX = 1;
} else if (check[0][x]==2) {
JOptionPane.showMessageDialog(null, "O is the winner");
winO = 1;
}
}
}
/** Check diagonals for winner */
if (((check[0][0]==check[1][1])&&(check[0][0]==check[2][2]))||
((check[2][0]==check[1][1])&&(check[1][1]==check[0][2]))){
if (check[1][1]==1) {
JOptionPane.showMessageDialog(null, "X is the winner");
winX = 1;
} else if (check[1][1]==2) {
JOptionPane.showMessageDialog(null, "O is the winner");
winO = 1;
}
}
/** Checks if the game is a tie */
/* if ((clicks==9) && (win==0)) {
JOptionPane.showMessageDialog(null, "The game is a tie");
}
*/}
void startPlaying() {
playing = new Thread(this);
playing.start();
gui.play.setEnabled(false);
}
public void run() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
To fix my problem I created a separate class.
Class one:
import java.awt.*;
import javax.swing.*;
public class TicTac extends JFrame {
TicTacEvent tictac = new TicTacEvent(this);
JPanel row1 = new JPanel();
JButton[][] boxes = new JButton[3][3];
JButton play = new JButton("Play");
JTextField blank1 = new JTextField();
JTextField blank2 = new JTextField();
JOptionPane win = new JOptionPane("Winner");
ImageIcon back = new ImageIcon("cardback.jpg");
public TicTac() {
super ("Tic Tac Toe");
setSize (500,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FlowLayout layout = new FlowLayout();
setLayout(layout);
int name = 0;
String newname;
GridLayout layout1 = new GridLayout(4, 3, 10, 10);
row1.setLayout(layout1);
for (int x=0; x<=2; x++){
for (int y=0; y<=2; y++){
name = name + 1;
newname = Integer.toString(name);
boxes[x][y] = new JButton(newname);
boxes[x][y].setIcon(back);
row1.add(boxes[x][y]);
}
}
row1.add(blank1);
row1.add(play);
row1.add(blank2);
add (row1);
play.addActionListener(tictac);
for (int x=0; x<=2; x++){
for (int y=0; y<=2; y++){
boxes[x][y].addActionListener(tictac);
}
}
setVisible(true);
}
public static void main(String[] arguments){
TicTac frame = new TicTac();
}
}
Class 2:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class TicTacEvent implements ItemListener, ActionListener, Runnable {
TicTac gui;
Thread playing;
ImageIcon a = new ImageIcon("x.jpg");
ImageIcon b = new ImageIcon("o.jpg");
int clicks = 0;
int win = 0;
int[][] check = new int[3][3];
public TicTacEvent (TicTac in){
gui = in;
for (int row=0; row<=2; row++){
for (int col=0; col<=2; col++){
check[row][col]=0;
}
}
}
public void actionPerformed (ActionEvent event) {
String command = event.getActionCommand();
if (command.equals("Play")) {
startPlaying();
}
if (command.equals("1")) {
b1();
}
if (command.equals("2")) {
b2();
}
if (command.equals("3")) {
b3();
}
if (command.equals("4")) {
b4();
} if (command.equals("5")) {
b5();
}
if (command.equals("6")) {
b6();
}
if (command.equals("7")) {
b7();
}
if (command.equals("8")) {
b8();
}
if (command.equals("9")) {
b9();
}
}
void b1() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[0][0].setIcon(a);
check[0][0] = 1;
} else {
gui.boxes[0][0].setIcon(b);
check[0][0] = 2;
}
winner();
}
void b2() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[0][1].setIcon(a);
check[0][1] = 1;
} else {
gui.boxes[0][1].setIcon(b);
check[0][1] = 2;
}
winner();
}
void b3() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[0][2].setIcon(a);
check[0][2] = 1;
} else { gui.boxes[0][2].setIcon(b);
check[0][2] = 2;
}
winner();
}
void b4() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[1][0].setIcon(a);
check[1][0] = 1;
} else {
gui.boxes[1][0].setIcon(b);
check[1][0] = 2;
}
winner();
}
void b5() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[1][1].setIcon(a);
check[1][1] = 1;
} else {
gui.boxes[1][1].setIcon(b);
check[1][1] = 2;
}
winner();
}
void b6() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[1][2].setIcon(a);
check[1][2] = 1;
} else {
gui.boxes[1][2].setIcon(b);
check[1][2] = 2;
}
winner();
}
void b7() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[2][0].setIcon(a);
check[2][0] = 1;
} else {
gui.boxes[2][0].setIcon(b);
check[2][0] = 2; }
winner();
}
void b8() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[2][1].setIcon(a);
check[2][1] = 1;
} else {
gui.boxes[2][1].setIcon(b);
check[2][1] = 2;
}
winner();
}
void b9() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[2][2].setIcon(a);
check[2][2] = 1;
} else {
gui.boxes[2][2].setIcon(b);
check[2][2] = 2;
}
winner();
}
void winner() {
/** Check rows for winner */
for (int x=0; x<=2; x++){
if ((check[x][0]==check[x][1])&&(check[x][0]==check[x][2])) {
if (check[x][0]==1) {
JOptionPane.showMessageDialog(null, "X is the winner");
win = 1;
} else if (check[x][0]==2){
JOptionPane.showMessageDialog(null, "Y is the winner");
win = 1;
}
}
}
/** Check columns for winner */
for (int x=0; x<=2; x++){
if ((check[0][x]==check[1][x])&&(check[0][x]==check[2][x])) {
if (check[0][x]==1) {
JOptionPane.showMessageDialog(null, "X is the winner"); win = 1;
} else if (check[0][x]==2) {
JOptionPane.showMessageDialog(null, "Y is the winner");
win = 1;
}
}
}
/** Check diagonals for winner */
if (((check[0][0]==check[1][1])&&(check[0][0]==check[2][2]))||
((check[2][0]==check[1][1])&&(check[1][1]==check[0][2]))){
if (check[1][1]==1) {
JOptionPane.showMessageDialog(null, "X is the winner");
win = 1;
} else if (check[1][1]==2) {
JOptionPane.showMessageDialog(null, "Y is the winner");
win = 1;
}
}
/** Checks if the game is a tie */
if ((clicks==9) && (win==0)) {
JOptionPane.showMessageDialog(null, "The game is a tie");
}
}
void startPlaying() {
playing = new Thread(this);
playing.start();
gui.play.setEnabled(false);
}
public void itemStateChanged(ItemEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void run() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
Your constructor requires you to pass in an existing TicTac as a parameter. In the code you show, you're trying to create a TicTac without doing so.
As #MadProgrammer points out, requiring a TicTac to create a TicTac creates something of a catch-22 situation: How can you ever create one without having one first? If, for some reason, you do need to create a TicTac with a reference to an existing TicTac, you need to create an additional constructor with no parameters (as your compiler is suggesting) to create the first one:
public TicTac() { }
(more accurately, your constructor can take parameters, it just cant require a TicTac):
class TicTac {
public TicTac(int size) { }
public TicTac(TicTac otherTicTac) { }
...
}
//elsewhere:
TicTac first = new TicTac(5); //or just TicTac first = new TicTac()
TicTac second = new TicTac(first);
However, I'm guessing that you don't really need a TicTac(TicTac otherTicTac) constructor (if so, tell me why), and that you're trying to do so as a result of a misunderstanding about how constructors work - in which case this might be a helpful read, for starters.
I have 3 classes for Tic Tac Toe.
Class 1: This is the main class and it hold the button and such
Class 2: The game itself calculates score and such
Class 3: Displays the score from class 2
I am trying to get the score from class 2 and display it in class 3
`Class 2`
`public class TicTacEvent implements ItemListener, ActionListener, Runnable {
TicTac gui;
Thread playing;
ImageIcon a = new ImageIcon("x.jpg");
ImageIcon b = new ImageIcon("o.jpg");
int clicks = 0;
int win = 0;
int winX = 0;
int winO = 0;
int tie = 0;
int[][] check = new int[3][3];
public TicTacEvent (TicTac in){
gui = in;
for (int row=0; row<=2; row++){
for (int col=0; col<=2; col++){
check[row][col]=0;
}
}
}
public void actionPerformed (ActionEvent event) {
String command = event.getActionCommand();
if (command.equals("Play")) {
startPlaying();
}
if (command.equals("1")) {
b1();
}
if (command.equals("2")) {
b2();
}
if (command.equals("3")) {
b3();
}
if (command.equals("4")) {
b4();
}
if (command.equals("5")) {
b5();
}
if (command.equals("6")) {
b6();
}
if (command.equals("7")) {
b7();
}
if (command.equals("8")) {
b8();
}
if (command.equals("9")) {
b9();
}
}
void b1() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[0][0].setIcon(a);
check[0][0] = 1;
} else {
gui.boxes[0][0].setIcon(b);
check[0][0] = 2;
}
winner();
}
void b2() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[0][1].setIcon(a);
check[0][1] = 1;
} else {
gui.boxes[0][1].setIcon(b);
check[0][1] = 2;
}
winner();
}
void b3() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[0][2].setIcon(a);
check[0][2] = 1;
} else {
gui.boxes[0][2].setIcon(b);
check[0][2] = 2;
}
winner();
}
void b4() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[1][0].setIcon(a);
check[1][0] = 1;
} else {
gui.boxes[1][0].setIcon(b);
check[1][0] = 2;
}
winner();
}
void b5() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[1][1].setIcon(a);
check[1][1] = 1;
} else {
gui.boxes[1][1].setIcon(b);
check[1][1] = 2;
}
winner();
}
void b6() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[1][2].setIcon(a);
check[1][2] = 1;
} else {
gui.boxes[1][2].setIcon(b);
check[1][2] = 2;
}
winner();
}
void b7() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[2][0].setIcon(a);
check[2][0] = 1;
} else {
gui.boxes[2][0].setIcon(b);
check[2][0] = 2;
}
winner();
}
void b8() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[2][1].setIcon(a);
check[2][1] = 1;
} else {
gui.boxes[2][1].setIcon(b);
check[2][1] = 2;
}
winner();
}
void b9() {
clicks = clicks + 1;
if ((clicks%2)==1){
gui.boxes[2][2].setIcon(a);
check[2][2] = 1;
} else {
gui.boxes[2][2].setIcon(b);
check[2][2] = 2;
}
winner();
}
void winner() {
/** Check rows for winner */
for (int x=0; x<=2; x++){
if ((check[x][0]==check[x][1])&&(check[x][0]==check[x][2])) {
if (check[x][0]==1) {
JOptionPane.showMessageDialog(null, "X is the winner");
winX = 1;
System.out.println(Integer.toString(winX));
} else if (check[x][0]==2){
JOptionPane.showMessageDialog(null, "O is the winner");
winO = 1;
}
}
}
/** Check columns for winner */
for (int x=0; x<=2; x++){
if ((check[0][x]==check[1][x])&&(check[0][x]==check[2][x])) {
if (check[0][x]==1) {
JOptionPane.showMessageDialog(null, "X is the winner");
winX = 1;
} else if (check[0][x]==2) {
JOptionPane.showMessageDialog(null, "O is the winner");
winO = 1;
}
}
}
/** Check diagonals for winner */
if (((check[0][0]==check[1][1])&&(check[0][0]==check[2][2]))||
((check[2][0]==check[1][1])&&(check[1][1]==check[0][2]))){
if (check[1][1]==1) {
JOptionPane.showMessageDialog(null, "X is the winner");
winX = 1;
} else if (check[1][1]==2) {
JOptionPane.showMessageDialog(null, "O is the winner");
winO = 1;
}
}
/** Checks if the game is a tie */
if ((clicks==9) && (win==0)) {
JOptionPane.showMessageDialog(null, "The game is a tie");
}
}
void startPlaying() {
playing = new Thread(this);
playing.start();
gui.play.setEnabled(false);
}
public void itemStateChanged(ItemEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void run() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
`Class 3`
`public class Score extends JFrame{
private JTextField xScore;
private JTextField oScore;
private JTextField tieScore;
private JButton reset;
public Score(){
JFrame frame = new JFrame("Score");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
FlowLayout score = new FlowLayout();
frame.setLayout(score);
xScore = new JTextField("X Wins: ");
oScore = new JTextField("O Wins: ");
tieScore = new JTextField("Ties: ");
reset = new JButton("Reset");
xScore.setBounds(0, 0, 100, 20);
oScore.setBounds(0, 30, 100, 20);
tieScore.setBounds(0, 60, 100, 20);
frame.add(xScore);
frame.add(oScore);
frame.add(tieScore);
frame.add(reset);
frame.setBackground(Color.BLACK);
frame.pack();
frame.setVisible(true);
}
}`
As discussed in your previous similar question from 30 min ago:
Use one JFrame. The other window should be a JDialog, although here a non-modal JDialog.
Use a getter method to allow one class to get the score String from another class.
The tricky part here that was not discussed as we did not have enough information at the time, is knowing when to pass the information to the Score JDialog. Here your main GUI should hold an instance of the Score JDialog, give this JDialog a setter method that would allow the main GUI to set the Score's score JTextField when the actual score changes.