neitu
neitu

Reputation: 21

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();
}
}

Upvotes: 0

Views: 124

Answers (1)

Andrew Thompson
Andrew Thompson

Reputation: 168825

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);
    }
}

Upvotes: 3

Related Questions