Search code examples
javaswingjbuttonvisibilitystatic-methods

JButton Only Works When Visibility is Set to True-Java


I am trying to make a simple checkers game basically, and I need the user to only be able to see the tiles and the pieces, not the button. When I set the visibility to True, the program works by giving me a test message of "Hey a button was pressed!" However, when I set the visibility to False (what I need it to be), I no longer get the test message. The only forum question I seen related to this from a general google search was to use repaint and revalidate, but those did not work and thus I removed those 2 lines of code. I normally would have a button class that would work great, but due to my code only accepting static and not normal, I have to implement jbutton directly in my main class. So what is wrong exactly? Here is my code and thanks in advance.

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

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

@SuppressWarnings("serial")
public class CheckersMain extends JButton implements ActionListener {

    private static JFrame window;
    private static Color winBackground=Color.GRAY;
    private static Color tile1Color=Color.WHITE;
    private static Color tile2Color=Color.BLACK;
    private static int windowWidth=1000;
    private static int windowHeight=1000;
    private static int setScreenLoc=500;
    private static int tileDimention=100;
    private static Board board;
    private static ArrayList<JButton> allButtons=new ArrayList<JButton>();
    private static ArrayList<Tile> allTiles;

    public static void main(String[] args) {
        window=new JFrame();
        window.setLayout(null);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setTitle("Checkers");
        window.setLocation(setScreenLoc,setScreenLoc);
        window.setSize(windowWidth,windowHeight);
        window.setResizable(false);
        window.getContentPane().setBackground(winBackground);
        window.setVisible(true);
        board=new Board(window,tileDimention,tile1Color,tile2Color);
        allTiles=board.setUp();
        setUpButtons();
        window.repaint();
    }

    private static void setUpButtons() {
        for (int i=0;i<allTiles.size();++i) {
            Tile currentTile=allTiles.get(i);
            JButton button=new JButton();
            button.setSize(tileDimention,tileDimention);
            button.setLocation(currentTile.getXlocation(),currentTile.getYlocation());
            window.add(button,0);
            button.addActionListener(new CheckersMain());
            button.setVisible(false);
            allButtons.add(button);
        }
    }

    private void buttonPressed() {
        System.out.println("Hey a button was pressed!");
    }
    public void actionPerformed(ActionEvent frame) {
        for (int i=0;i<allButtons.size();++i) {
            if (frame.getSource()==allButtons.get(i)) {
                buttonPressed();
            }
        }
    }
}

Solution

  • This sounds like a good place to use the Glass Pane: https://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html

    The glass pane is invisible, but still receives mouse move and click events. Add a click listener on the glass pane and get the mouse position, then check if that position is over the space where your 'hidden' button would be.