Hello, I need help with a program im doing with JavaFX on Netbeans. It\'s a Tic-
ID: 3718875 • Letter: H
Question
Hello, I need help with a program im doing with JavaFX on Netbeans.
It's a Tic-Tac-Toe game with two phases, where it starts with a screen that allows you to name both players and have a start button.
Then in the second window, it will have the game board on the left side and on the right side, it should show the players names that were inputted from the start screen and their name should change to red whenever it is their turn.
Then finally, whoever wins, a popup shows up saying that player won.
I have the basics of it down, but I need help with bringing the players names inputted into the first screen to show up next to the board and how to make their name light up whenever it is their turn.
I gave the code below, Thank you
Main
TicTacToe.java
package TicTacToe;
import javafx.application.Application;
import javafx.stage.Stage;
public class TicTacToe extends Application
{
@Override
public void start(Stage pstage) throws Exception {
pstage.setWidth(400);
pstage.setMaxWidth(400);
pstage.setHeight(250);
pstage.setMaxHeight(250);
pstage.show();
pstage.centerOnScreen();
pstage.setTitle("TicTacToe");
First.welcomePlayers(pstage);
}
public static void main(String[] args) {
Application.launch(args);
}
}
GameBoard.Java
package TicTacToe;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class GameBoard {
private boolean aTurn = false;
private Button[] but = new Button[9];
private int cot = 0;
private final Stage st;
private final Scene sce;
public GameBoard(Stage stage)
{
ActionToButtons(but);
GridPane GP = new GridPane();
GP.setPadding(new Insets(20));
int x=0;
for (int y=0;y<3;y++){
for (int j=0;j<3;j++) {
if (x > 8) {
break;
}
GP.add(but[x], y, j);
x++;
}
}
sce = new Scene(GP, 230, 230);
stage.setScene(sce);
stage.show();
stage.setResizable(false);
this.st = stage;
}
private void ActionToButtons(Button[] bt) {
for (int i = 0; i < 9; i++) {
Button b = new Button();
bt[i] = b;
b.setPrefWidth(80);
b.setMaxWidth(80);
b.setPrefHeight(80);
b.setMaxHeight(80);
Turn(b);
}
}
public Button[] getButtons(){
return but;
}
private void Turn(Button button)
{
button.setOnAction((ActionEvent arg0) -> {
String win = "";
if (button.getText().isEmpty()) {
if (!aTurn) {
button.setText("X");
aTurn = true;
} else {
button.setText("O");
aTurn = false;
}
win = button.getText();
cot++;
}
if(but[0].getText().equals(win) && but[1].getText().equals(win) && but[2].getText().equals(win) ||
but[3].getText().equals(win) && but[4].getText().equals(win) && but[5].getText().equals(win) ||
but[6].getText().equals(win) && but[7].getText().equals(win) && but[8].getText().equals(win) ||
but[0].getText().equals(win) && but[3].getText().equals(win) && but[6].getText().equals(win) ||
but[1].getText().equals(win) && but[4].getText().equals(win) && but[7].getText().equals(win) ||
but[2].getText().equals(win) && but[5].getText().equals(win) && but[8].getText().equals(win) ||
but[0].getText().equals(win) && but[4].getText().equals(win) && but[8].getText().equals(win) ||
but[2].getText().equals(win) && but[4].getText().equals(win) && but[6].getText().equals(win)) {
showUp p = new showUp(st);
p.setMessage(win + " Wins!");
}
else if (cot >= 9){
showUp p= new showUp(st);
p.setMessage("Draw");
}
}
);
}
}
Welcome.java
package TicTacToe;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public abstract class Welcome {
public static void welcomePlayers(Stage primaryStage)
{
GridPane GD = new GridPane();
Pos alignment = null;
GD.setAlignment(alignment);
GD.setPadding(new Insets(20));
Label Fname = new Label("Player 1");
TextField Ftext = new TextField();
Label Sname = new Label("Player 2");
TextField Stext = new TextField();
Label Err = new Label("");
Button letsPlayBtn = new Button("Start");
GridPane.setMargin(Fname, new Insets(10));
GridPane.setMargin(Ftext, new Insets(10));
GridPane.setMargin(Sname, new Insets(10));
GridPane.setMargin(Stext, new Insets(10));
GridPane.setMargin(letsPlayBtn, new Insets(10));
GridPane.setMargin(Err, new Insets(10));
GD.add(Fname, 0, 0);
GD.add(Ftext, 1, 0);
GD.add(Sname, 0, 1);
GD.add(Stext, 1, 1);
GD.add(Err, 0, 2);
GD.add(letsPlayBtn, 0, 3);
GridPane.setColumnSpan(Err, 2);
GridPane.setColumnSpan(letsPlayBtn, 2);
Scene Fscene = new Scene(GD);
primaryStage.setScene(Fscene);
letsPlayBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent arg0) {
if (Ftext.getText().isEmpty()
|| Stext.getText().isEmpty()) {
Err.setText("Players have not finished naming themselves");
Err.setStyle("-fx-text-fill: red");
Ftext.requestFocus();
return;
}
Board board = new Board(primaryStage);
}
});
Ftext.setOnKeyPressed((KeyEvent arg0) -> {
Err.setText("");
});
Stext.setOnKeyPressed((KeyEvent arg0) -> {
Err.setText("");
});
}
}
Player.java
package TicTacToe;
public enum Player
{
Fname("-fx-text-fill: darkred;"),
Sname("-fx-text-fill: darkblue;");
private final String style;
Player(String st)
{
this.style = st;
}
public String getStyle() {
return style;
}
}
showUp.java
package ttt2;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class showUp {
private final Label show;
private final Button Quit;
private final Button CButton;
private final Scene sc;
private final VBox lay;
public showUp(Stage st) {
show = new Label();
show.setStyle("-fx-font-color:red");
Quit = new Button("Quit");
CButton = new Button("Play Again");
lay = new VBox();
lay.setAlignment(Pos.CENTER);
VBox.setMargin(show, new Insets(10));
VBox.setMargin(Quit, new Insets(10));
VBox.setMargin(CButton, new Insets(10));
lay.getChildren().add(show);
lay.getChildren().add(Quit);
lay.getChildren().add(CButton);
sc = new Scene(lay);
st.setScene(sc);
Quit.setOnAction((ActionEvent arg0) -> {
st.close();
});
CButton.setOnAction((ActionEvent arg0) -> {
GameBoard gameboard = new GameBoard(st);
});
}
public void setMessage(String message) {
this.show.setText(message);
}
}
Explanation / Answer
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.beans.value.*;
import javafx.event.*;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import java.util.*;
public class TicTacToe extends Application {
@Override public void start(Stage stage) throws Exception {
GameManager gameManager = new GameManager();
Scene scene = gameManager.getGameScene();
scene.getStylesheets().add(
getResource(
"tictactoe-blueskin.css"
)
);
stage.setTitle("Tic-Tac-Toe");
stage.getIcons().add(SquareSkin.crossImage);
stage.setScene(scene);
stage.show();
}
private String getResource(String resourceName) {
return getClass().getResource(resourceName).toExternalForm();
}
public static void main(String[] args) {
Application.launch(TicTacToe.class);
}
}
class GameManager {
private Scene gameScene;
private Game game;
GameManager() {
newGame();
}
public void newGame() {
game = new Game(this);
if (gameScene == null) {
gameScene = new Scene(game.getSkin());
} else {
gameScene.setRoot(game.getSkin());
}
}
public void quit() {
gameScene.getWindow().hide();
}
public Game getGame() {
return game;
}
public Scene getGameScene() {
return gameScene;
}
}
class GameControls extends HBox {
GameControls(final GameManager gameManager, final Game game) {
getStyleClass().add("game-controls");
visibleProperty().bind(game.gameOverProperty());
Label playAgainLabel = new Label("Play Again?");
playAgainLabel.getStyleClass().add("info");
Button playAgainButton = new Button("Yes");
playAgainButton.getStyleClass().add("play-again");
playAgainButton.setDefaultButton(true);
playAgainButton.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent actionEvent) {
gameManager.newGame();
}
});
Button exitButton = new Button("No");
playAgainButton.getStyleClass().add("exit");
exitButton.setCancelButton(true);
exitButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
gameManager.quit();
}
});
getChildren().setAll(
playAgainLabel,
playAgainButton,
exitButton
);
}
}
class StatusIndicator extends HBox {
private final ImageView playerToken = new ImageView();
private final Label playerLabel = new Label("Current Player: ");
StatusIndicator(Game game) {
getStyleClass().add("status-indicator");
bindIndicatorFieldsToGame(game);
playerToken.setFitHeight(32);
playerToken.setPreserveRatio(true);
playerLabel.getStyleClass().add("info");
getChildren().addAll(playerLabel, playerToken);
}
private void bindIndicatorFieldsToGame(Game game) {
playerToken.imageProperty().bind(
Bindings.when(
game.currentPlayerProperty().isEqualTo(Square.State.NOUGHT)
)
.then(SquareSkin.noughtImage)
.otherwise(
Bindings.when(
game.currentPlayerProperty().isEqualTo(Square.State.CROSS)
)
.then(SquareSkin.crossImage)
.otherwise((Image) null)
)
);
playerLabel.textProperty().bind(
Bindings.when(
game.gameOverProperty().not()
)
.then("Current Player: ")
.otherwise(
Bindings.when(
game.winnerProperty().isEqualTo(Square.State.EMPTY)
)
.then("Draw")
.otherwise("Winning Player: ")
)
);
}
}
class Game {
private GameSkin skin;
private Board board = new Board(this);
private WinningStrategy winningStrategy = new WinningStrategy(board);
private ReadOnlyObjectWrapper<Square.State> currentPlayer = new ReadOnlyObjectWrapper<>(Square.State.CROSS);
public ReadOnlyObjectProperty<Square.State> currentPlayerProperty() {
return currentPlayer.getReadOnlyProperty();
}
public Square.State getCurrentPlayer() {
return currentPlayer.get();
}
private ReadOnlyObjectWrapper<Square.State> winner = new ReadOnlyObjectWrapper<>(Square.State.EMPTY);
public ReadOnlyObjectProperty<Square.State> winnerProperty() {
return winner.getReadOnlyProperty();
}
private ReadOnlyBooleanWrapper drawn = new ReadOnlyBooleanWrapper(false);
public ReadOnlyBooleanProperty drawnProperty() {
return drawn.getReadOnlyProperty();
}
public boolean isDrawn() {
return drawn.get();
}
private ReadOnlyBooleanWrapper gameOver = new ReadOnlyBooleanWrapper(false);
public ReadOnlyBooleanProperty gameOverProperty() {
return gameOver.getReadOnlyProperty();
}
public boolean isGameOver() {
return gameOver.get();
}
public Game(GameManager gameManager) {
gameOver.bind(
winnerProperty().isNotEqualTo(Square.State.EMPTY)
.or(drawnProperty())
);
skin = new GameSkin(gameManager, this);
}
public Board getBoard() {
return board;
}
public void nextTurn() {
if (isGameOver()) return;
switch (currentPlayer.get()) {
case EMPTY:
case NOUGHT: currentPlayer.set(Square.State.CROSS); break;
case CROSS: currentPlayer.set(Square.State.NOUGHT); break;
}
}
private void checkForWinner() {
winner.set(winningStrategy.getWinner());
drawn.set(winningStrategy.isDrawn());
if (isDrawn()) {
currentPlayer.set(Square.State.EMPTY);
}
}
public void boardUpdated() {
checkForWinner();
}
public Parent getSkin() {
return skin;
}
}
class GameSkin extends VBox {
GameSkin(GameManager gameManager, Game game) {
getChildren().addAll(
game.getBoard().getSkin(),
new StatusIndicator(game),
new GameControls(gameManager, game)
);
}
}
class WinningStrategy {
private final Board board;
private static final int NOUGHT_WON = 3;
private static final int CROSS_WON = 30;
private static final Map<Square.State, Integer> values = new HashMap<>();
static {
values.put(Square.State.EMPTY, 0);
values.put(Square.State.NOUGHT, 1);
values.put(Square.State.CROSS, 10);
}
public WinningStrategy(Board board) {
this.board = board;
}
public Square.State getWinner() {
for (int i = 0; i < 3; i++) {
int score = 0;
for (int j = 0; j < 3; j++) {
score += valueOf(i, j);
}
if (isWinning(score)) {
return winner(score);
}
}
for (int i = 0; i < 3; i++) {
int score = 0;
for (int j = 0; j < 3; j++) {
score += valueOf(j, i);
}
if (isWinning(score)) {
return winner(score);
}
}
int score = 0;
score += valueOf(0, 0);
score += valueOf(1, 1);
score += valueOf(2, 2);
if (isWinning(score)) {
return winner(score);
}
score = 0;
score += valueOf(2, 0);
score += valueOf(1, 1);
score += valueOf(0, 2);
if (isWinning(score)) {
return winner(score);
}
return Square.State.EMPTY;
}
public boolean isDrawn() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board.getSquare(i, j).getState() == Square.State.EMPTY) {
return false;
}
}
}
return getWinner() == Square.State.EMPTY;
}
private Integer valueOf(int i, int j) {
return values.get(board.getSquare(i, j).getState());
}
private boolean isWinning(int score) {
return score == NOUGHT_WON || score == CROSS_WON;
}
private Square.State winner(int score) {
if (score == NOUGHT_WON) return Square.State.NOUGHT;
if (score == CROSS_WON) return Square.State.CROSS;
return Square.State.EMPTY;
}
}
class Board {
private final BoardSkin skin;
private final Square[][] squares = new Square[3][3];
public Board(Game game) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
squares[i][j] = new Square(game);
}
}
skin = new BoardSkin(this);
}
public Square getSquare(int i, int j) {
return squares[i][j];
}
public Node getSkin() {
return skin;
}
}
class BoardSkin extends GridPane {
BoardSkin(Board board) {
getStyleClass().add("board");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
add(board.getSquare(i, j).getSkin(), i, j);
}
}
}
}
class Square {
enum State { EMPTY, NOUGHT, CROSS }
private final SquareSkin skin;
private ReadOnlyObjectWrapper<State> state = new ReadOnlyObjectWrapper<>(State.EMPTY);
public ReadOnlyObjectProperty<State> stateProperty() {
return state.getReadOnlyProperty();
}
public State getState() {
return state.get();
}
private final Game game;
public Square(Game game) {
this.game = game;
skin = new SquareSkin(this);
}
public void pressed() {
if (!game.isGameOver() && state.get() == State.EMPTY) {
state.set(game.getCurrentPlayer());
game.boardUpdated();
game.nextTurn();
}
}
public Node getSkin() {
return skin;
}
}
class SquareSkin extends StackPane {
static final Image noughtImage = new Image(
"http://icons.iconarchive.com/icons/double-j-design/origami-colored-pencil/128/green-cd-icon.png"
);
static final Image crossImage = new Image(
"http://icons.iconarchive.com/icons/double-j-design/origami-colored-pencil/128/blue-cross-icon.png"
);
private final ImageView imageView = new ImageView();
SquareSkin(final Square square) {
getStyleClass().add("square");
imageView.setMouseTransparent(true);
getChildren().setAll(imageView);
setPrefSize(crossImage.getHeight() + 20, crossImage.getHeight() + 20);
setOnMousePressed(new EventHandler<MouseEvent>() {
@Override public void handle(MouseEvent mouseEvent) {
square.pressed();
}
});
square.stateProperty().addListener(new ChangeListener<Square.State>() {
@Override public void changed(ObservableValue<? extends Square.State> observableValue, Square.State oldState, Square.State state) {
switch (state) {
case EMPTY: imageView.setImage(null); break;
case NOUGHT: imageView.setImage(noughtImage); break;
case CROSS: imageView.setImage(crossImage); break;
}
}
});
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.