0

I'm making a javafx app and when I run it the IDE gives no errors. The application window doesn't show but I can see that the program's running in task manager.

I have tried running the code in both Eclipse and IntelliJ. I tried running a new application with just a title and it worked so it's something to do with the particular code.

package main;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import javafx.scene.text.Font;

public class Main extends Application {
    public boolean isX=true;
    public Button[] bs=new Button[9];
    Label turn = new Label("Turn: X");
    public int i=0;

    public void start(Stage stage){
        BorderPane bp = new BorderPane();
        bp.setPrefSize(310, 350);
        turn.setFont(Font.font(20));
        bp.setTop(turn);

        makeButtons(bs);
        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);

        grid.add(bs[0],0,0);
        grid.add(bs[1],1,0);
        grid.add(bs[2],2,0);
        grid.add(bs[3],0,1);
        grid.add(bs[4],1,1);
        grid.add(bs[5],2,1);
        grid.add(bs[6],0,2);
        grid.add(bs[7],1,2);
        grid.add(bs[8],2,2);

        bp.setCenter(grid);

        stage.setScene(new Scene(bp));
        stage.setTitle("Tic tac toe");
        stage.show();
    }

    void makeButtons(Button[] bs){
        while (i<bs.length){
            bs[i]=new Button(" ");
            bs[i].setFont(Font.font("Monospaced", 40));
            bs[i].setPrefSize(90, 90);
            bs[i].setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent mouseEvent) {
                    if (isX){
                        isX=false;
                        bs[i].setText("X");
                        turn.setText("Turn: O");
                    } else {
                        isX=true;
                        bs[i].setText("O");
                        turn.setText("Turn: X");
                    }
                }
            });
        }

    }

    public static void main(String[] args){
        launch(Main.class);
    }
}

Update: I finished noughts and crosses

package main;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import javafx.scene.text.Font;

public class Main extends Application {
    public boolean isX=true;
    public Button[] bs=new Button[9];
    Label turn = new Label("Turn: X");
    int goes =0;

    public void start(Stage stage){
        BorderPane bp = new BorderPane();
        bp.setPrefSize(310, 350);
        turn.setFont(Font.font(20));
        bp.setTop(turn);

        makeButtons(bs);
        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);

        grid.add(bs[0],0,0);
        grid.add(bs[1],1,0);
        grid.add(bs[2],2,0);
        grid.add(bs[3],0,1);
        grid.add(bs[4],1,1);
        grid.add(bs[5],2,1);
        grid.add(bs[6],0,2);
        grid.add(bs[7],1,2);
        grid.add(bs[8],2,2);

        bp.setCenter(grid);

        stage.setScene(new Scene(bp));
        stage.setTitle("Noughts and crosses");
        stage.show();
    }

    void makeButtons(Button[] bs){
        for (int i=0;i<bs.length;i++){
            bs[i]=new Button(" ");
            bs[i].setFont(Font.font("Monospaced", 40));
            bs[i].setPrefSize(90, 90);
            bs[i].setOnAction(this::handleTurn);
        }

    }

    private void handleTurn(ActionEvent e){
        goes++;
        if (goes>4&&won()){
            return;
        }
        Button b = (Button) e.getSource();
        if (!b.getText().equals(" ")){
            return;
        }
        if (isX) {
            isX = false;
            b.setText("X");
            turn.setText("Turn: O");
        } else {
            isX=true;
            b.setText("O");
            turn.setText("Turn: X");
        }
        if (goes==9){
            turn.setText("Game over: not turns left");
        }
    }

    private boolean won(){
        //rows
        for (int i=0;i< 7;i+=3){
            if (!bs[i].getText().equals(" ")&&bs[i].getText().equals(bs[i+1].getText())&&bs[i].getText().equals(bs[i+2].getText())){
                turn.setText(bs[i].getText()+" wins!");
                return true;
            }
        }
        //columns
        for (int i=0;i<3;i++){
            if (!bs[i].getText().equals(" ")&&bs[i].getText().equals(bs[i+3].getText())&&bs[i].getText().equals(bs[i+6].getText())){
                turn.setText(bs[i].getText()+" wins!");
                return true;
            }
        }
        //diagonals
        if (!bs[0].getText().equals(" ")&&bs[0].getText().equals(bs[4].getText())&&bs[0].getText().equals(bs[8].getText())){
            turn.setText(bs[0].getText()+" wins!");
            return true;
        }

        if (!bs[2].getText().equals(" ")&&bs[2].getText().equals(bs[4].getText())&&bs[2].getText().equals(bs[6].getText())){
            turn.setText(bs[2].getText()+" wins!");
            return true;
        }
        return false;
    }

    public static void main(String[] args){
        launch(Main.class);
    }
}
1

1 Answer 1

4

You aren't changing the value of i in the while loop in method makeButtons and therefore the while loop never terminates.

Also, you should add an action listener to the buttons and not a mouse listener. Refer to this tutorial.

Consider the following code.
(Note: More explanations after the code.)

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import javafx.scene.text.Font;

public class Main extends Application {
    public boolean isX=true;
    public Button[] bs=new Button[9];
    Label turn = new Label("Turn: X");

    public void start(Stage stage){
        BorderPane bp = new BorderPane();
        bp.setPrefSize(310, 350);
        turn.setFont(Font.font(20));
        bp.setTop(turn);

        makeButtons(bs);
        GridPane grid = new GridPane();
        grid.setHgap(10);
        grid.setVgap(10);

        grid.add(bs[0],0,0);
        grid.add(bs[1],1,0);
        grid.add(bs[2],2,0);
        grid.add(bs[3],0,1);
        grid.add(bs[4],1,1);
        grid.add(bs[5],2,1);
        grid.add(bs[6],0,2);
        grid.add(bs[7],1,2);
        grid.add(bs[8],2,2);

        bp.setCenter(grid);

        stage.setScene(new Scene(bp));
        stage.setTitle("Tic tac toe");
        stage.show();
    }

    void makeButtons(Button[] bs){
        int i = 0;
        while (i<bs.length){
            bs[i]=new Button(" ");
            bs[i].setFont(Font.font("Monospaced", 40));
            bs[i].setPrefSize(90, 90);
            bs[i].setOnAction(this::handleTurn);
            i++;
        }
    }

    private void handleTurn(ActionEvent event) {
        Button button = (Button) event.getSource();
        if (isX) {
            isX = false;
            button.setText("X");
            turn.setText("Turn: O");
        }
        else {
            isX = true;
            button.setText("O");
            turn.setText("Turn: X");
        }
    }

    public static void main(String[] args){
        launch(Main.class);
    }
}

The above code uses method references which were introduced in Java 8. Here is the relevant line from the above code:

bs[i].setOnAction(this::handleTurn);

Whenever any of the buttons are clicked, method handleTurn is executed.

Notice that, in that method, I obtain the actual button that was clicked by calling method getSource (of class ActionEvent).

This is how it looks when I run the above code.

screen capture

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.