0

I am trying to make minesweeper. When I click on the JButton I want the button to hide. I have accomplished this but the button does not cover the entire JPanel. It always leaves some of the panel on the top visible.

I have tried setting the preferred size, vertical and horizontal alignment.

Why is it doing this? How can I fix it?

class canvas extends JFrame {

    public static JPanel[] panels;
    public static Tile[] tiles;
    canvas(int size){
        JFrame theGUI = new JFrame();
        panels = new JPanel[size*size]; //creates panels and tiles, the tiles contain color, if it is 
                                          a bomb ect. 
        tiles = new Tile[size*size];
        Container con = theGUI.getContentPane();
        Graphics g;

        for(int i = 0; i < panels.length; i++) {
            JPanel temp = new JPanel();
            temp.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));//adds borders
            temp.setBorder(BorderFactory.createLineBorder(Color.black,1));

            JButton button = new JButton();
            button.setBackground(Color.GRAY);
            button.setAlignmentY(0.0f);//tried to see if vertical align would fix it, it didnt               
            button.setPreferredSize(new Dimension(70,70));
            button.addActionListener(new Action() {
                public void actionPerformed(ActionEvent event) {
                button.setVisible(false);
                }
            });
            temp.add(button);
            Tile tempTile = new Tile();
            panels[i] = temp;
            tiles[i] = tempTile; 
            tiles[i].color = Color.green;
            panels[i].setBackground(tiles[i].color);
            con.add(panels[i]);
        }
        con.setLayout(new GridLayout(size,size));
        theGUI.setTitle("mine sweeper");
        theGUI.setSize(size*40, size*40);
        theGUI.setVisible(true);    
   }
}

The problem I am trying to fix:

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 1
    1. Do not set the size of your GUI but rather call `pack()` on the JFrame after adding all components and before setting it visible. This should right-size most everything (if wired correctly) – Hovercraft Full Of Eels Jun 15 '20 at 22:44
  • 2. Best way to make the button "invisible" is to swap it for a JLabel. I did this in [my minesweeper app](https://stackoverflow.com/a/7016492/522444) using CardLayouts. – Hovercraft Full Of Eels Jun 15 '20 at 22:46
  • 2
    1) Class names should start with an upper case character. Learn by example from the class names of the JDK. 2) Don't call you class "Canvas". There is already an AWT component by that name which will cause confusion. 3) Why do you set the size of the frame "* 40" but you set the button size to 70? See point one from Hovercrafts first comment for the proper solution. 4) Don't use static variables. You should not have static variables of methods for something like this. 5) The first setBorder() statement does nothing since it will be replaced by the second statement. – camickr Jun 16 '20 at 01:33
  • 2
    *the JButton does not cover the entire JPanel. It always leaves some of the JPanel on the top visible.* - not sure what you mean. I would expect to see 5 pixels around all sides of the button since a JPanel uses a FlowLayout which has 5 pixel spacing between components. Post a proper [mre] demonstrating the problem. We should be able to copy/paste/compile and test the code. This means you need to remove the code unrelated to the problem, like the Tiles class. – camickr Jun 16 '20 at 01:34
  • 2
    Side note: you are creating a `JFrame` instance by `JFrame theGUI = new JFrame();`, so there is no need for `extends JFrame` – c0der Jun 16 '20 at 03:49

1 Answers1

1

I think you can achieve your goal with simpler code. You just need to add the JButtons directly to a JPanel that uses GridLayout as its layout manager. Consider the following code.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

public class MineSweeper implements ActionListener, Runnable {
    private JFrame  frame;

    public void actionPerformed(ActionEvent event) {
        Object obj = event.getSource();
        if (obj instanceof JButton) {
            JButton button = (JButton) obj;
            button.setVisible(false);
        }
    }

    public void run() {
        showGui();
    }

    private JButton createButton() {
        JButton button = new JButton();
        button.setPreferredSize(new Dimension(40, 40));
        button.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
        button.addActionListener(this);
        return button;
    }

    private JPanel createMineField() {
        JPanel mineField = new JPanel(new GridLayout(10, 10));
        mineField.setBackground(Color.GREEN);
        for (int i = 0; i < 100; i++) {
            mineField.add(createButton());
        }
        return mineField;
    }

    private void showGui() {
        frame = new JFrame("Mine Sweeper");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.add(createMineField(), BorderLayout.CENTER);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    /**
     * Start here.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new MineSweeper());
    }
}
Abra
  • 19,142
  • 7
  • 29
  • 41