I am making a Tic Tac Toe Program in java because i am learning java and i thought a simple project would be a great place to start. This is my code so far:
public class Start {
public static void main(String[] args) {
GameTicTacToe gameTicTacToe = new GameTicTacToe();
gameTicTacToe.windowBirth();
}
}
And,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GameTicTacToe implements ActionListener {
private int gridSize = 3;
private JButton[] gridButton = new JButton[(gridSize * gridSize)];
private JPanel grid = new JPanel(new GridLayout(gridSize, gridSize, 0, 0));
private JFrame windowTicTacToe = new JFrame("Tisk, Task, Toes");
private int[] gridButtonOwner = new int[(gridSize * gridSize)];
private int turn = 1;
private int HolerHor, HolerVer, HolerDia1, HolerDia2;
Thread winnerBlue = new Thread() {
public void run() {
for (int a = 0; a < 4; a++) {
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setBackground(Color.BLUE);
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setBackground(Color.WHITE);
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
}
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setEnabled(true);
gridButtonOwner[i] = 0;
}
}
};
Thread winnerRed = new Thread() {
public void run() {
for (int a = 0; a < 4; a++) {
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setBackground(Color.RED);
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setBackground(Color.WHITE);
}
try {
Thread.sleep(300);
} catch (InterruptedException e) {
}
}
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setEnabled(true);
gridButtonOwner[i] = 0;
}
}
};
public void windowBirth() {
for (int i = 0; i < gridButton.length; i++) {
gridButtonOwner[i] = 0;
gridButton[i] = new JButton("");
gridButton[i].addActionListener(this);
gridButton[i].setBackground(Color.WHITE);
grid.add(gridButton[i]);
}
windowTicTacToe.setDefaultCloseOperation(3);
windowTicTacToe.setLocation(400, 200);
windowTicTacToe.setPreferredSize(new Dimension(400, 400));
windowTicTacToe.add(grid);
windowTicTacToe.pack();
windowTicTacToe.setVisible(true);
}
public void actionPerformed(ActionEvent gridButtonClicked) {
for (int i = 0; i < gridButton.length; i++) {
if (gridButtonClicked.getSource() == gridButton[i]) {
if (turn == 1) {
turn = 2;
gridButtonOwner[i] = 1;
gridButton[i].setBackground(Color.blue);
gridButton[i].setEnabled(false);
} else {
turn = 1;
gridButtonOwner[i] = 2;
gridButton[i].setBackground(Color.red);
gridButton[i].setEnabled(false);
}
}
}
checkWinner();
}
public void checkWinner() {
for (int a = 1; a < 3; a++) {
HolerDia1 = a;
HolerDia2 = a;
for (int b = 0; b < gridSize; b++) {
HolerHor = a;
HolerVer = a;
for (int c2 = 0; c2 < gridSize; c2++) {
HolerHor = (HolerHor * gridButtonOwner[((b * gridSize) + c2)])/ a;
HolerVer = (HolerVer * gridButtonOwner[((c2 * gridSize) + b)])/ a;
}
if (HolerHor == a || HolerVer == a) {
winnerAnimation(a);
}
}
for(int h = 0;h < gridSize; h++){
HolerDia1 = (HolerDia1 * gridButtonOwner[h * (gridSize + 1)]) / a;
HolerDia2 = (HolerDia2 * gridButtonOwner[(h * (gridSize - 1)) + (gridSize - 1)]) / a;
}
if (HolerDia1 == a || HolerDia2 == a) {
winnerAnimation(a);
}
}
}
public void winnerAnimation(int b) {
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setEnabled(false);
}
if (b == 1){
winnerBlue.start();
}else{
winnerRed.start();
}
}
}
This is my question, When a player wins, for example Player 1 (Blue), it plays the animation (Flashing the board Blue). But when Player 1 wins again, the program crashes.
I looked into it a little and found that you can't start a thread twice because you just can't.
How would i go about pausing the thread, then restarting it when i need to?
You could simply create a new Thread and run it when needed. But regardless of this, I'd do the animation using a Swing Timer as it's simpler and safer since you don't have to worry about pernicious intermittent crashes from accidently stepping on the Swing thread, the EDT.
For e.g.,
public void myWinner(final Color flashColor) {
int timerDelay = 300;
new javax.swing.Timer(timerDelay , new ActionListener() {
private static final int COUNTER_MAX = 5;
int counter = 0;
public void actionPerformed(ActionEvent e) {
if (counter >= COUNTER_MAX) { // time to stop
((Timer)e.getSource()).stop();
for (int i = 0; i < gridButton.length; i++) {
gridButton[i].setBackground(Color.white); // just to be sure
gridButton[i].setEnabled(true);
gridButtonOwner[i] = 0;
}
}
Color bckgrndColor = (counter % 2 == 0) ? flashColor : Color.white;
for (JButton button : gridButton) {
button.setBackground(bckgrndColor);
}
counter++;
}
}).start();
}
In your case, where the animation thread is replayed, you may want to:
Runnable
object, e.g. rather than creating an anonymous Thread
object, create an anonymous Runnable
.Then simply recreate the thread and start it:
public void winnerAnimation(int b)
{
...
if (b == 1)
{
animationThread = new Thread(winnerBlue);
animationThread.start();
}
else
{
animationThread = new Thread(winnerRed);
animationThread.start();
}
}
BTW, you may want to consider the fact that Swing is not thread-safe when writing your Thread
s or Runnable
s.
Use Semaphores.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With