Home > Software engineering >  How to keep a button visible when clicking on other buttons?
How to keep a button visible when clicking on other buttons?

Time:11-02

I'm creating a tic tac toe game, and I have created 2 buttons "Quit" and "Replay". When I click on any other buttons, those 2 buttons disappear. I'd be happy if you tell what I can do to have them visible when I click on any other buttons.

As you can see in both screenshots, before I click on any buttons, both are visible, but when I click on any button, both disappear, and I have to hover my mouse over them for them appear again.

Click here for the image

enter image description here

Below is all of code



public static void main(String[] args) {
    TickTacToe tik = new TickTacToe();
}
 
    Random random = new Random();
    JFrame frame = new JFrame();
    JPanel title_panel = new JPanel();
    JPanel button_panel = new JPanel();
    JLabel textfield = new JLabel();
    JButton[] buttons_array = new JButton[9];
    int i =0;
    JPanel panel;
     
    JButton Replaybutton,Quitbutton;
    boolean player1_turn;

 
    TickTacToe(){
        JButton Replay,Quit;
        Replay = new JButton();
         
        Replay.setText("Replay?");
        Replay.setForeground(Color.cyan);
        Replay.setFont(new Font("Courgette",Font.BOLD,17));
        Replay.setBackground(new Color(25,60,80));
        Replay.setBounds(70,10, 100,45);
         
        Quit = new JButton();
         
        Quit.setText("Quit!");
        Quit.setForeground(Color.black);
        Quit.setFont(new Font("Courgette",Font.BOLD,19));
        Quit.setBackground(new Color(145,80,120));
        Quit.setBounds(620, 10, 100, 45);
     
        ////////////////////////////////////////////////////////
         
        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);
        //Below line is for centring our frame in the middle.
        frame.setLocationRelativeTo(null);
         
         
     
        textfield.setBackground(Color.black);
        textfield.setForeground(new Color(80,170,20));
        textfield.setFont(new Font("Courgette",Font.PLAIN,50));
        //The below method is for centering our text in the center.
        textfield.setHorizontalAlignment(JLabel.CENTER);
        textfield.setText("Tik-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_array[i] = new JButton();
            button_panel.add(buttons_array[i]);
            buttons_array[i].setFont(new Font("InkFree",Font.BOLD,120));
            buttons_array[i].setFocusable(false);
            buttons_array[i].addActionListener(this);
             
         
        }
         
     
         
     
        frame.add(Replay);
        frame.add(Quit);
        frame.setResizable(false);
        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_array[i]) {
                 
                if(player1_turn) {
                    if(buttons_array[i].getText()=="") {
                        buttons_array[i].setForeground(Color.red);
                        buttons_array[i].setText("X");
                        player1_turn =false;
                        textfield.setText("O Turn");
                        check();
                         
                    }
                }
                 
                else {
                    if(buttons_array[i].getText()=="") {
                        buttons_array[i].setForeground(Color.blue);
                        buttons_array[i].setText("O");
                        player1_turn =true;
                        textfield.setText("X Turn");
                        check();
                         
                    }
                }
            }
             
        }
         
    }
     
    public void firstTurn() {
         
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
             
            e.printStackTrace();
        }
         
        if(random.nextInt(2)==0) {
            player1_turn = true;
            textfield.setText("X Turn");
             
        }else if(random.nextInt(2) == 1) {
             
            player1_turn = false;
            textfield.setText("O Turn");
             
        }
    }
     
    public void check() {
         
        // Checking for x win Conditiotns.
        if(
                (buttons_array[0].getText() == "X") &&
                buttons_array[1].getText() ==  "X" &&
                buttons_array[2].getText() ==  "X"
                 
                ) {
             
            xWins(0,1,2);
        }
         
        if(
                (buttons_array[3].getText() == "X") &&
                buttons_array[4].getText() ==  "X" &&
                buttons_array[5].getText() ==  "X"
                 
                ) {
             
            xWins(3,4,5);
        }
         
        if(
                (buttons_array[6].getText() == "X") &&
                buttons_array[7].getText() == "X" &&
                buttons_array[8].getText() == "X"
                 
                ) {
             
            xWins(6,7,8);
        }
     
        if(
                (buttons_array[0].getText() == "X") &&
                buttons_array[3].getText() ==  "X" &&
                buttons_array[6].getText() ==  "X"
                 
                ) {
             
            xWins(0,3,6);
        }
         
        if(
                (buttons_array[1].getText() == "X") &&
                buttons_array[4].getText() ==  "X" &&
                buttons_array[7].getText() ==  "X"
                 
                ) {
             
            xWins(1,4,7);
        }
         
        if(
                (buttons_array[2].getText() == "X") &&
                buttons_array[5].getText() ==  "X" &&
                buttons_array[8].getText() ==  "X"
                 
                ) {
             
            xWins(2,5,8);
        }
         
        if(
                (buttons_array[0].getText() == "X") &&
                buttons_array[4].getText() == "X" &&
                buttons_array[8].getText() ==  "X"
                 
                ) {
             
            xWins(0,4,8);
        }
         
         
        if(
                (buttons_array[2].getText() == "X") &&
                buttons_array[4].getText() ==  "X" &&
                buttons_array[6].getText() ==  "X"
                 
                ) {
             
            xWins(2,4,6);
        }
         
         
        if(
                (buttons_array[0].getText() == "O") &&
                buttons_array[1].getText() ==  "O"  &&
                buttons_array[2].getText() ==  "O"
                 
                ) {
             
             
            oWins(0,1,2);
             
        }
         
        if(
                (buttons_array[3].getText() == "O") &&
                buttons_array[4].getText() ==  "O" &&
                buttons_array[5].getText() ==  "O"
                 
                ) {
             
            oWins(3,4,5);
        }
         
        if(
                (buttons_array[6].getText() == "O") &&
                buttons_array[7].getText() ==  "O" &&
                buttons_array[8].getText() ==  "O"
                 
                ) {
             
            oWins(6,7,8);
        }
         
        if(
                (buttons_array[0].getText() == "O") &&
                buttons_array[3].getText() ==  "O" &&
                buttons_array[6].getText() ==  "O"
                 
                ) {
             
            oWins(0,3,6);
        }
         
        if(
                (buttons_array[1].getText() == "O") &&
                buttons_array[4].getText() ==  "O" &&
                buttons_array[7].getText() ==  "O"
                 
                ) {
             
            oWins(1,4,7);
        }
         
        if(
                (buttons_array[2].getText() == "O") &&
                buttons_array[5].getText() ==  "O" &&
                buttons_array[8].getText() ==  "O"
                 
                 
                ) {
             
            oWins(2,5,8);
        }
         
         
        if(
                (buttons_array[0].getText() == "O") &&
                buttons_array[4].getText() ==  "O" &&
                buttons_array[8].getText() ==  "O"
                 
                ) {
             
            oWins(0,4,8);
        }
         
         
        if(
                (buttons_array[2].getText() == "O") &&
                buttons_array[4].getText() ==  "O" &&
                buttons_array[6].getText() ==  "O"
                 
                ) {
             
            oWins(2,4,6);
         
             
        }
         
    }
        //////////////////////////////////////////////////////////////////////////////////
             
           
     
         
     
     
    public void xWins(int a, int b, int c) {
         
        buttons_array[a].setBackground(new Color(50,15,80));
        buttons_array[b].setBackground(new Color(150,15,80));
        buttons_array[c].setBackground(Color.BLACK);
         
        for(int i=0;i<9;i  ) {
            buttons_array[i].setEnabled(false);
        }

CodePudding user response:

Introduction

Oracle has a helpful tutorial, Example

I used Swing layout managers to create a button JPanel and a tic-tac-toe grid JPanel. You can press any button you want, and all the buttons remain visible on the JFrame.

I left all the coloring and fonts for you to add.

Explanation

When I create a Swing GUI, I use the model-view-controller (MVC) pattern. This pattern allows me to separate my concerns and focus on one small part of the application at a time.

For a Swing GUI, the MVC pattern is defined as:

  1. The view reads information from the model.
  2. The view does not update the model.
  3. The controller updates the model and repaints / revalidates the view.

A Swing GUI can have many controller classes. I created three controller classes for this tic-tac-toe game. Two of the three controller classes are expressed as lambda expressions because they are simple.

I created 5 different classes. One class makes up the application model, one class defines the view, and three controller classes manage the application.

Model

The GameModel class is a plain Java getter/setter class that creates a logical tic-tac-toe board and keeps track of whose turn it is.

View

Every Swing application must start with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and updated on the Event Dispatch Thread.

I use a JFrame and create a button JPanel and a grid JPanel. The JFrame has a default BorderLayout. I put the button JPanel at NORTH and the grid JPanel in the CENTER.

The button JPanel uses a FlowLayout and the grid JPanel uses, you guessed it, a GridLayout. I added an empty border around both JPanels to add some whitespace to the GUI.

I used a Box createHorizontalStrut method to add some whitespace to the button JPanel.

Controller

The reset button and quit button controllers are simple lambda expressions.

I made nine instances of the MoveListener class, one for each button in the tic-tac-toe grid. This makes the actionPerformed code rather simple. The only logic is to check to make sure the square is empty before making the move.

For some reason, checking for spaces didn't work, so I check for the absence of an 'X' or an 'O'.

Code

Here's the complete runnable code. I made the additional classes inner classes so I could post this code as one block.

I tested this code and it works. Save it somewhere safe before you make lots of changes and then gripe that it doesn't work.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class SimpleTicTacToeGUI implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SimpleTicTacToeGUI());
    }

    private final GameModel model;
    
    private JButton[] gridButtons;
    
    private JFrame frame;

    private JLabel turnLabel;
    
    public SimpleTicTacToeGUI() {
        this.model = new GameModel();
    }

    @Override
    public void run() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createButtonPanel(), BorderLayout.NORTH);
        frame.add(createGrid(), BorderLayout.CENTER);

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

    private JPanel createButtonPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
        Font font = panel.getFont().deriveFont(16f);
        
        JButton resetButton = new JButton("Replay?");
        resetButton.setFont(font);
        resetButton.addActionListener(event -> {
            model.resetModel();
            updateGUI();
            enableButtons();
        });
        panel.add(resetButton);
        
        panel.add(Box.createHorizontalStrut(30));

        turnLabel = new JLabel(model.getTurn()   "'s turn");
        turnLabel.setFont(font);
        panel.add(turnLabel);
        
        panel.add(Box.createHorizontalStrut(30));

        JButton quitButton = new JButton("Quit!");
        quitButton.setFont(font);
        quitButton.addActionListener(event -> {
            frame.dispose();
            System.exit(0);
        });
        panel.add(quitButton);

        return panel;
    }

    private JPanel createGrid() {
        JPanel panel = new JPanel(new GridLayout(0, 3));
        panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
        Font font = panel.getFont().deriveFont(Font.BOLD, 72f);
        
        gridButtons = new JButton[model.getBoard().length];
        for (int index = 0; index < gridButtons.length; index  ) {
            gridButtons[index] = new JButton(" ");
            MoveListener listener = new MoveListener(this, model, index);
            gridButtons[index].addActionListener(listener);
            gridButtons[index].setFont(font);
            gridButtons[index].setPreferredSize(new Dimension(96, 96));
            panel.add(gridButtons[index]);
        }

        return panel;
    }
    
    public void updateGUI() {
        char[] board = model.getBoard();
        for (int index = 0; index < gridButtons.length; index  ) {
            String s = Character.toString(board[index]);
            gridButtons[index].setText(s);
        }
        turnLabel.setText(model.getTurn()   "'s turn");
    }
    
    public void disableButtons() {
        for (int index = 0; index < gridButtons.length; index  ) {
            gridButtons[index].setEnabled(false);
        }
    }
    
    private void enableButtons() {
        for (int index = 0; index < gridButtons.length; index  ) {
            gridButtons[index].setEnabled(true);
        }
    }
    
    public JButton getButton(int index) {
        return gridButtons[index];
    }
    
    public class MoveListener implements ActionListener {
        
        private final int index;
        
        private final SimpleTicTacToeGUI view;
        
        private final GameModel model;

        public MoveListener(SimpleTicTacToeGUI view, GameModel model,
                int index) {
            this.view = view;
            this.model = model;
            this.index = index;
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            String s = view.getButton(index).getText();
            if (!(s.equals("X") || s.equals("O"))) {
                model.makeMove(index);
                view.updateGUI();
                if (model.isGameOver()) {
                    view.disableButtons();
                }
            }
        }
        
    }
    
    public class GameModel {
        
        private char[] board;
        private char turn;
        
        public GameModel() {
            resetModel();
        }
        
        public void resetModel() {
            this.board = new char[9];
            this.turn = 'X';
        }
        
        public void makeMove(int index) {
            board[index] = turn;
            turn = (turn == 'X') ? 'O' : 'X';
        }
        
        public boolean isGameOver() {
            int[][] indexes = { { 0, 1, 2 }, { 3, 4, 5 }, { 6, 7, 8 },
                    { 0, 3, 6 }, { 1, 4, 7 }, { 2, 5, 8 }, { 0, 4, 8 },
                    { 2, 4, 6 } };
            for (int index = 0; index < indexes.length; index  ) {
                if (checkRow('X', indexes[index])
                        || checkRow('O', indexes[index])) {
                    return true;
                }
            }
            return false;
        }
        
        private boolean checkRow(char player, int[] indexes) {
            for (int index = 0; index < indexes.length; index  ) {
                if (board[indexes[index]] != player) {
                    return false;
                }
            }
            
            return true;
        }

        public char getTurn() {
            return turn;
        }

        public char[] getBoard() {
            return board;
        }
        
    }

}
  • Related