'JButton freezes after being clicked

I'm aware that this question has already been answered but the answers mostly depend on the code itself. In this program I'm trying to open 2 windows of board by pressing the button on the start window. But the button freezes after program being executed. Could somebody explain the reason and suggest a way to do this as above explained

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

public class Board extends JFrame {
    JFrame frame = new JFrame();
    JPanel title_panel = new JPanel();
    JPanel button_panel = new JPanel();
    JLabel textfield = new JLabel();
    Scanner sc = new Scanner(System.in);
    int n = sc.nextInt();
    int size = n*n;
    JButton[] buttons = new JButton[size];
    Board(){
    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("Game");
    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);
    
    button_panel.setLayout(new GridLayout(n,n));
    button_panel.setBackground(new Color (150,150,150));
    
    boardmaker();
    
    title_panel.add(textfield);
    frame.add(title_panel,BorderLayout.NORTH);
    frame.add(button_panel);
}

public void boardmaker(){
    for(int i=0; i<size; i++){
        buttons[i] = new JButton();
        button_panel.add(buttons[i]);
        buttons[i].setFont(new Font("MV Boli",Font.BOLD,120));
        buttons[i].setFocusable(false);
    }
}

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class StartPage implements ActionListener {
JFrame frame = new JFrame();
JButton btn = new JButton();


StartPage(){
    btn.setBounds(100, 160, 200, 40);
    btn. setFocusable(false);
    btn.addActionListener(this);
    
    
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(btn);
    frame.setSize(420, 420);
    frame.setLayout(null);
    frame.setVisible(true);
}

@Override
public void actionPerformed(ActionEvent e) {
    if(e.getSource() == btn){
        Board board = new Board();
    }
}
}

public class Main {
public static int boardSize;
public static void main(String[] args) {
    
   //boardSize = sc.nextInt(); 
   
   StartPage s = new StartPage();
   //Board gui = new Board();        
   //gui.boardmaker();
}
}


Solution 1:[1]

Don't mix GUIs with IO from the console. It will block the Event Dispatch Thread and cause the GUI to 'freeze' as it does when the button is clicked.

Add a prompt to the GUI with a JSpinner instead. Once the prompt (a modal dialog) is dismissed, the selected board size will be available in the SpinnerNumberModel.

Here is that alternate strategy, in code:

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

public class Board {
    JFrame frame = new JFrame();
    JPanel title_panel = new JPanel();
    JPanel button_panel = new JPanel(new BorderLayout());
    JLabel title_label = new JLabel("midterm project");
    JButton[][] buttons;

    Board(int n) {
        buttons = new JButton[n][n];

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setBackground(new Color(50, 50, 50));
        frame.setLayout(new BorderLayout());

        title_label.setBackground(new Color(25, 25, 25));
        title_label.setForeground(new Color(25, 255, 0));
        title_label.setFont(new Font("Ink Free", Font.BOLD, 75));
        title_label.setHorizontalAlignment(JLabel.CENTER);
        title_label.setOpaque(true);

        title_panel.add(title_label);

        button_panel.setLayout(new GridLayout(n, n));
        button_panel.setBackground(new Color(150, 150, 150));
        button_panel.setPreferredSize(new Dimension(600,600));

        boardMaker(n);

        frame.add(title_panel, BorderLayout.PAGE_START);
        frame.add(button_panel);

        frame.pack();
        frame.setVisible(true);
    }

    public void boardMaker(int n) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                buttons[i][j] = new JButton();
                button_panel.add(buttons[i][j]);
                buttons[i][j].setFont(new Font("MV Boli", Font.BOLD, 120));
                buttons[i][j].setFocusable(false);
            }
        }
    }

    public static int startPage() {
        SpinnerNumberModel snm = new SpinnerNumberModel(8,4,20,1);
        int result = JOptionPane.showConfirmDialog(null, new JSpinner(snm),
                "Choose Board Size", JOptionPane.OK_CANCEL_OPTION);
        if (result==JOptionPane.OK_OPTION) {
            return snm.getNumber().intValue();
        }
        return 0;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                int n = Board.startPage();
                if (n>0) new Board(n);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andrew Thompson