0

I'm a beginner to coding. I'm using IntelliJ on a MacBook M1 Pro. So far most things went great and the compiling time is fast. Apps where everything runs in the Terminal work perfectly.

Unfortunately, when I use Swing instances like JPanel & JFrame there seems to be a delay or complete bug. I'm watching this tutorial on a Tic Tac Toe game. I've done everything the exact same but at this point when I run it only a gray square panel with a white top panel is being displayed. No text.

Weirdly, when I resize the window, there is a short freeze of the window, followed by the spinning loading wheel and then the text "Tic-Tac-Toe" appears on the top with the correct back-&foreground colors.

When I copy the whole final code from the video it works for some reason. I've triple checked everything, so far it's identical but it's not working correctly for some reason.

There's a TicTacToe.java and Main.java file in the project.

My code so far in TicTacToe.java :

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;


    public class TicTacToe implements ActionListener {

        Random random = new Random();
        JFrame frame = new JFrame();
        JPanel title_panel = new JPanel();
        JPanel button_panel = new JPanel();
        JLabel textfield = new JLabel();
        JButton[] buttons = new JButton[9];
        boolean player1_turn;


        TicTacToe() {
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(800, 800);
            frame.getContentPane().setBackground(new Color(50,50,50));
            frame.setLocationRelativeTo(null);
            frame.setLayout(new BorderLayout());
            frame.setVisible(true);


            textfield.setBackground(new Color(9, 21, 227));
            textfield.setForeground(new Color(25, 255, 0));
            textfield.setFont(new Font("Ink Free", Font.BOLD, 75));
            textfield.setHorizontalAlignment(JLabel.CENTER);
            textfield.setText("Tic-Tac-Toe");
            textfield.setOpaque(true);

            title_panel.setLayout(new BorderLayout());
            title_panel.setBounds(0,0,800,100);

            title_panel.add(textfield);
            frame.add(title_panel,BorderLayout.NORTH);
            

        }


        @Override
        public void actionPerformed(ActionEvent e) {

        }

        public void firstTurn() {

        }

        public void check() {

        }

        public void xWins(int a, int b, int c) {

        }

        public void oWins(int a, int b, int c) {

        }
    }

The video tutorial's code:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class TicTacToe implements ActionListener{

    Random random = new Random();
    JFrame frame = new JFrame();
    JPanel title_panel = new JPanel();
    JPanel button_panel = new JPanel();
    JLabel textfield = new JLabel();
    JButton[] buttons = new JButton[9];
    boolean player1_turn;

    TicTacToe(){
        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800,800);
        frame.getContentPane().setBackground(new Color(50,50,50));
        frame.setLayout(new BorderLayout());
        frame.setVisible(true);
        
        textfield.setBackground(new Color(25,25,25));
        textfield.setForeground(new Color(25,255,0));
        textfield.setFont(new Font("Ink Free",Font.BOLD,75));
        textfield.setHorizontalAlignment(JLabel.CENTER);
        textfield.setText("Tic-Tac-Toe");
        textfield.setOpaque(true);
        
        title_panel.setLayout(new BorderLayout());
        title_panel.setBounds(0,0,800,100);
        
        button_panel.setLayout(new GridLayout(3,3));
        button_panel.setBackground(new Color(150,150,150));
        
        for(int i=0;i<9;i++) {
            buttons[i] = new JButton();
            button_panel.add(buttons[i]);
            buttons[i].setFont(new Font("MV Boli",Font.BOLD,120));
            buttons[i].setFocusable(false);
            buttons[i].addActionListener(this);
        }
        
        title_panel.add(textfield);
        frame.add(title_panel,BorderLayout.NORTH);
        frame.add(button_panel);
        
        firstTurn();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        
        for(int i=0;i<9;i++) {
            if(e.getSource()==buttons[i]) {
                if(player1_turn) {
                    if(buttons[i].getText()=="") {
                        buttons[i].setForeground(new Color(255,0,0));
                        buttons[i].setText("X");
                        player1_turn=false;
                        textfield.setText("O turn");
                        check();
                    }
                }
                else {
                    if(buttons[i].getText()=="") {
                        buttons[i].setForeground(new Color(0,0,255));
                        buttons[i].setText("O");
                        player1_turn=true;
                        textfield.setText("X turn");
                        check();
                    }
                }
            }           
        }
    }
    
    public void firstTurn() {
        
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        if(random.nextInt(2)==0) {
            player1_turn=true;
            textfield.setText("X turn");
        }
        else {
            player1_turn=false;
            textfield.setText("O turn");
        }
    }
    
    public void check() {
        //check X win conditions
        if(
                (buttons[0].getText()=="X") &&
                (buttons[1].getText()=="X") &&
                (buttons[2].getText()=="X")
                ) {
            xWins(0,1,2);
        }
        if(
                (buttons[3].getText()=="X") &&
                (buttons[4].getText()=="X") &&
                (buttons[5].getText()=="X")
                ) {
            xWins(3,4,5);
        }
        if(
                (buttons[6].getText()=="X") &&
                (buttons[7].getText()=="X") &&
                (buttons[8].getText()=="X")
                ) {
            xWins(6,7,8);
        }
        if(
                (buttons[0].getText()=="X") &&
                (buttons[3].getText()=="X") &&
                (buttons[6].getText()=="X")
                ) {
            xWins(0,3,6);
        }
        if(
                (buttons[1].getText()=="X") &&
                (buttons[4].getText()=="X") &&
                (buttons[7].getText()=="X")
                ) {
            xWins(1,4,7);
        }
        if(
                (buttons[2].getText()=="X") &&
                (buttons[5].getText()=="X") &&
                (buttons[8].getText()=="X")
                ) {
            xWins(2,5,8);
        }
        if(
                (buttons[0].getText()=="X") &&
                (buttons[4].getText()=="X") &&
                (buttons[8].getText()=="X")
                ) {
            xWins(0,4,8);
        }
        if(
                (buttons[2].getText()=="X") &&
                (buttons[4].getText()=="X") &&
                (buttons[6].getText()=="X")
                ) {
            xWins(2,4,6);
        }
        //check O win conditions
        if(
                (buttons[0].getText()=="O") &&
                (buttons[1].getText()=="O") &&
                (buttons[2].getText()=="O")
                ) {
            oWins(0,1,2);
        }
        if(
                (buttons[3].getText()=="O") &&
                (buttons[4].getText()=="O") &&
                (buttons[5].getText()=="O")
                ) {
            oWins(3,4,5);
        }
        if(
                (buttons[6].getText()=="O") &&
                (buttons[7].getText()=="O") &&
                (buttons[8].getText()=="O")
                ) {
            oWins(6,7,8);
        }
        if(
                (buttons[0].getText()=="O") &&
                (buttons[3].getText()=="O") &&
                (buttons[6].getText()=="O")
                ) {
            oWins(0,3,6);
        }
        if(
                (buttons[1].getText()=="O") &&
                (buttons[4].getText()=="O") &&
                (buttons[7].getText()=="O")
                ) {
            oWins(1,4,7);
        }
        if(
                (buttons[2].getText()=="O") &&
                (buttons[5].getText()=="O") &&
                (buttons[8].getText()=="O")
                ) {
            oWins(2,5,8);
        }
        if(
                (buttons[0].getText()=="O") &&
                (buttons[4].getText()=="O") &&
                (buttons[8].getText()=="O")
                ) {
            oWins(0,4,8);
        }
        if(
                (buttons[2].getText()=="O") &&
                (buttons[4].getText()=="O") &&
                (buttons[6].getText()=="O")
                ) {
            oWins(2,4,6);
        }
    }
    
    public void xWins(int a,int b,int c) {
        buttons[a].setBackground(Color.GREEN);
        buttons[b].setBackground(Color.GREEN);
        buttons[c].setBackground(Color.GREEN);
        
        for(int i=0;i<9;i++) {
            buttons[i].setEnabled(false);
        }
        textfield.setText("X wins");
    }
    public void oWins(int a,int b,int c) {
        buttons[a].setBackground(Color.GREEN);
        buttons[b].setBackground(Color.GREEN);
        buttons[c].setBackground(Color.GREEN);
        
        for(int i=0;i<9;i++) {
            buttons[i].setEnabled(false);
        }
        textfield.setText("O wins");
    }
}

I'm thinking it's something with perhaps the JDK or an incompatibility with mac and IntelliJ, I dont know. I've already reinstalled IntelliJ and reset it to factory settings.

If anyone has any ideas please share. I've googled a lot and couldn't find any solution.

Syneptic
  • 1
  • 2
  • 2
    Where is your `Main.java` file? And you realize you can put other classes and the main in the same file (makes it easier to work on imo). And please don't post images or links to outside code. – WJS Jun 27 '22 at 15:47
  • Construct and manipulate Swing GUI objects _only_ on the [event dispatch thread](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html); more [here](https://stackoverflow.com/a/7158505/230513). – trashgod Jun 27 '22 at 15:53
  • @WJS The Main.java is in the same src folder as TicTacToe.java. Well I did realize that, it's just that's how they did it in the tutorial – Syneptic Jun 27 '22 at 15:54
  • Why don't you move `setVisible(true)` right before `firstTurn()`. Why make anything visible before you are done setting up? And why are you sleeping for 2 seconds? – WJS Jun 27 '22 at 16:01
  • 5
    instead of videos, I would strongly recommend WRITTEN tutorials, specially the Oracle's one: [The Java™ Tutorials](https://docs.oracle.com/javase/tutorial/) (kind of the developers of Java) – user16320675 Jun 27 '22 at 16:04
  • @trashgod I would agree except for construct. Constructing a JButton via new isn't done on the EDT. Perhaps I misunderstood what you meant. – WJS Jun 27 '22 at 16:04
  • 1
    @WJS that's working!!! Idk man, it was working in the video for the guy, I don't see why it shouldn't work on my PC the same way, everything else does. Well, thanks a lot! This did the trick – Syneptic Jun 27 '22 at 16:05
  • BTW, I learn lots of things from YouTube. But I have never found it a good source for learning to code (imho). I suggest you start by looking at answers on this site to see how to do graphics. There are lots of good examples. Personally, I prefer books. – WJS Jun 27 '22 at 16:06
  • @WJS I do try to get a lot of infos from here. I'm still pretty new to the whole coding world. YouTube is a pretty good spot to find broad information and then head over to stack overflow to specify questions and tasks. By the way, I had no idea stack overflow had such an incredible response time. You guys responded within the first couple minutes. I definitely wouldn't have expected that. – Syneptic Jun 27 '22 at 16:10
  • @Syneptic * that's working!!! Idk man, it was working in the video for the guy,* Perhaps his PC was faster. – WJS Jun 27 '22 at 16:10
  • BTW, Welcome to StackOverFlow. Recommend you take the [tour]. – WJS Jun 27 '22 at 16:12
  • @WJS while that could be the a possibility, it wouldn't really make sense to me. Note how it wouldn't work at all at first until I resized the window which caused it to display the text. It wasn't a question of time but instead giving it a 'trigger' – Syneptic Jun 27 '22 at 16:12
  • @WJS much appreciated, I'll look into the Tour. – Syneptic Jun 27 '22 at 16:13
  • 1
    @WJS: I'm paraphrasing the quote [here](https://stackoverflow.com/a/7158505/230513). I share your skepticism of coding videos. Good eye on premature `setVisible()`; it's a common error. – trashgod Jun 27 '22 at 16:16
  • I just noted your test for victory. I recommend you rewrite your `check()` method to use `if/else` clauses. Once a check is successful, why keep on checking after you return from declaring the winner? And consider this. Why check for both X and 0 wins in the same method? If one player just went the other player would have already won or not gone yet. One way this could be done by passing a `boolean` to determine which player to check. This may not be an issue now, but it could be in the future when you reset for another game. – WJS Jun 27 '22 at 16:31
  • @WJS I haven't gotten to that part (in the video) yet but I'll try your suggestion. :) thx for the hint – Syneptic Jun 27 '22 at 16:37
  • 2
    And this will be my last comment. :) Don't be using `==` to test Strings or any other `Object` for equality. Use `.equals`. You can use `==` for primitives or to test objects for `null`. Your program works because Strings are interned (cached) so all the X's are the same object as are Y's. And I checked the video and the in spite of good intentions, some bad techniques are being demonstrated there. – WJS Jun 27 '22 at 17:02
  • @WJS true he actually said that he did some sub-optimal coding because he didn't think the video would get that much traction. and yes, I did learn about that in a Udemy Java course! Good reminder, thanks :) – Syneptic Jun 27 '22 at 17:32

0 Answers0