-2

I am attempting my first go at JFrames in Java, and whenever I run my program an empty window shows up. I have added my buttons, my panel, yet it is completely blank. Is there anything specific about JFrame that I should know that could cause this mistake? The final product has no buttons at all. I have checked to see that every method has been called.

As a clarification, I am not asking for code revisions, as my code is too long and I don't know how to simplify it, nor do I know enough about the problem to do so, in order to provide an example. The reason I am posting is to ask about the nature of JFrame and under what conditions it would be an empty screen like this. I also looked at the post for how to simplify code, and it doesn't seem to apply(correct me if I'm wrong) because my problem is a lack of turnout, so removing code bit-by-bit will not result in the error disappearing.

Full Code :

    public class MineSweeperVisual extends JFrame{

private JButton[] buttons;
private JPanel panel;
private String[][] grid;
private int height;
private int width;
private JButton flagButton;
private boolean flag;
private JLabel result;


public MineSweeperVisual(int height2, int width2, int bombs) {
    height = height2;
    width = width2;
    buttons = new JButton[height * width];
    flag = false;
    result = new JLabel("Playing");

    grid = new String[height][width];
    for (int i = 0; i < bombs; i++) {
        int x = (int) (Math.random()*width);
        int y = (int) (Math.random()*height);
        grid[y][x] = "BH";
    }
    grid = resetGrid(grid, height, width);

    loadButtons();
    createFlagButton();
    createPanel();

    setSize(20 * width, 20 * height);
    setLocationRelativeTo(null);
}

public void createPanel() {
    panel = new JPanel();
    for(JButton i: buttons)
        panel.add(i);
    panel.add(flagButton);
    panel.add(result);
    setBackground(Color.BLACK);
}

public void loadButtons() {
    for (int i = 0; i < height * width; i ++) {
        buttons[i] = createGameButton(i);
    }
}

public JButton createGameButton(int i) {
    JButton button = new JButton(grid[i / width][i % height].substring(0,1));
    button.setPreferredSize(new Dimension(20,20));
    int y = i / 10;
    int x = i % 10;

    class RevealListener implements ActionListener {
    public void actionPerformed(ActionEvent event) {
        if (flag) {
            grid[y][x] = grid[y][x].substring(0,1) + "F";
        } else {
            grid[y][x] = grid[y][x].substring(0,1) + "R";
            if (grid[y][x].substring(0,1).equals("B")) {
                result.setText("You lost due to explosion");
            }
            grid = zeroChange(grid, height, width, x, y);
                for (int y1 = 0; y1 < height; y1 ++) {
                    for (int x1 = 0; x1 < width; x1++) {
                        if (grid[y1][x1].substring(0,2).equals("0R")) {
                            grid = adjacentToZeroChange(grid, height, width, x1, y1);
                        }
                    }
                }
            }
        }
    }

    ActionListener listener = new RevealListener();
    button.addActionListener(listener);
    return button;
}

private void createFlagButton () {
    flagButton = new JButton("Flag Mode");

    class FlagListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            if (!flag)
                flag = true;
            else
                flag = false;
        }
    }
    ActionListener listener = new FlagListener();
    flagButton.addActionListener(listener);
}

public static void main(String[] args) throws IOException {
    Scanner in = new Scanner(System.in);

    System.out.print("Enter the first dimension of the grid: ");
    int width = in.nextInt();

    System.out.print("Enter the second dimension of the grid: ");
    int height = in.nextInt();

    System.out.print("Enter the amount of bombs on the grid: ");
    int bombs = in.nextInt();

    JFrame frame = new MineSweeperVisual(height, width, bombs);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}public static String[][] adjacentToZeroChange(String[][] grid1, int height, int width, int x, int y) {
    String[][] grid = grid1;
    if (grid[y][x].substring(0,1).equals("0")) {
        if (y - 1 >= 0 && x - 1 >= 0 && grid[y - 1][x - 1] != null && !grid[y - 1][x - 1].substring(1,2).equals("F"))   {
            grid[y - 1][x - 1] = "" + grid[y - 1][x - 1].substring(0,1) + "R";
        }
        if (y - 1 >= 0 && grid[y - 1][x] != null && !grid[y - 1][x].substring(1,2).equals("F")) {
            grid[y - 1][x]  = "" + grid[y - 1][x].substring(0,1) + "R";
        }
        if (y - 1 >= 0 && x + 1 < width && grid[y - 1][x + 1] != null && !grid[y - 1][x + 1].substring(1,2).equals("F")) {
            grid[y - 1][x + 1] =  "" + grid[y - 1][x + 1].substring(0,1) + "R";
        }
        if (x - 1 >= 0 && grid[y][x - 1] != null && !grid[y][x - 1].substring(1,2).equals("F")) {
            grid[y][x - 1] =  "" + grid[y][x - 1].substring(0,1) + "R";
        }
        if (x + 1 < width && grid[y][x + 1] != null && !grid[y][x + 1].substring(1,2).equals("F"))  {
            grid[y][x + 1] = "" + grid[y][x + 1].substring(0,1) + "R";
        }
        if (y + 1 < height && x - 1 >= 0 && grid[y + 1][x - 1] != null && !grid[y + 1][x - 1].substring(1,2).equals("F"))   {
            grid[y + 1][x - 1]  =  "" + grid[y + 1][x - 1].substring(0,1) + "R";
        }
        if (y + 1 < height && grid[y + 1][x] != null && !grid[y + 1][x].substring(1,2).equals("F")) {
            grid[y + 1][x] = "" + grid[y + 1][x].substring(0,1) + "R";
        }
        if (y + 1 < height && x + 1 < width && grid[y + 1][x + 1] != null && !grid[y + 1][x + 1].substring(1,2).equals("F"))    {
            grid[y + 1][x + 1] = "" + grid[y + 1][x + 1].substring(0,1) + "R";
        }
    }
    return grid;
}
public static String[][] zeroChange(String[][] grid1, int height, int width, int x, int y) {
    String[][] grid = grid1;
    if (y - 1 >= 0 && x - 1 >= 0 && grid[y - 1][x - 1] != null && grid[y - 1][x - 1].substring(0,2).equals("0H"))   {
        grid[y - 1][x - 1] = "0R";
        grid = zeroChange(grid, height, width, y -1, x -1);
    }
    if (y - 1 >= 0 && grid[y - 1][x] != null && grid[y - 1][x].substring(0,2).equals("0H")) {
        grid[y - 1][x]  = "0R";
        grid = zeroChange(grid, height, width, y -1, x);
    }
    if (y - 1 >= 0 && x + 1 < width && grid[y - 1][x + 1] != null && grid[y - 1][x + 1].substring(0,2).equals("0H")) {
        grid[y - 1][x + 1] = "0R";
        grid = zeroChange(grid, height, width, y -1, x +1);
    }
    if (x - 1 >= 0 && grid[y][x - 1] != null && grid[y][x - 1].substring(0,2).equals("0H")) {
        grid[y][x - 1] = "0R";
        grid = zeroChange(grid, height, width, y, x -1);
    }
    if (x + 1 < width && grid[y][x + 1] != null && grid[y][x + 1].substring(0,2).equals("0H"))  {
        grid[y][x + 1] = "0R";
        grid = zeroChange(grid, height, width, y, x +1);
    }
    if (y + 1 < height && x - 1 >= 0 && grid[y + 1][x - 1] != null && grid[y + 1][x - 1].substring(0,2).equals("0H"))   {
        grid[y + 1][x - 1]  = "0R";
        grid = zeroChange(grid, height, width, y +1, x -1);
    }
    if (y + 1 < height && grid[y + 1][x] != null && grid[y + 1][x].substring(0,2).equals("0H")) {
        grid[y + 1][x] = "0R";
        grid = zeroChange(grid, height, width, y +1, x);
    }
    if (y + 1 < height && x + 1 < width && grid[y + 1][x + 1] != null && grid[y + 1][x + 1].substring(0,2).equals("0H"))    {
        grid[y + 1][x + 1] = "0R";
        grid = zeroChange(grid, height, width, y +1, x +1);
    }

    if (grid[y][x].substring(0,1).equals("0")) {
        grid = adjacentToZeroChange(grid, height, width, x, y);
    }

    return grid;
}
public static int spotCheck(String[][] grid, int x, int y, int width, int height) {
    int bAmount = 0;
    if (y - 1 >= 0 && x - 1 >= 0 && grid[y - 1][x - 1] != null && grid[y - 1][x - 1].substring(0,1).equals("B"))    {
        bAmount++;
    }
    if (y - 1 >= 0 && grid[y - 1][x] != null && grid[y - 1][x].substring(0,1).equals("B")) {
        bAmount++;
    }
    if (y - 1 >= 0 && x + 1 < width && grid[y - 1][x + 1] != null && grid[y - 1][x + 1].substring(0,1).equals("B")) {
        bAmount++;
    }
    if (x - 1 >= 0 && grid[y][x - 1] != null && grid[y][x - 1].substring(0,1).equals("B"))  {
        bAmount++;
    }
    if (x + 1 < width && grid[y][x + 1] != null && grid[y][x + 1].substring(0,1).equals("B"))   {
        bAmount++;
    }
    if (y + 1 < height && x - 1 >= 0 && grid[y + 1][x - 1] != null && grid[y + 1][x - 1].substring(0,1).equals("B"))    {
        bAmount++;
    }
    if (y + 1 < height && grid[y + 1][x] != null && grid[y + 1][x].substring(0,1).equals("B"))  {
        bAmount++;
    }
    if (y + 1 < height && x + 1 < width && grid[y + 1][x + 1] != null && grid[y + 1][x + 1].substring(0,1).equals("B")) {
        bAmount++;
    }
    return bAmount;
}
public static String[][] resetGrid(String[][] grid, int height, int width) {
    String[][] change = grid;
    for (int y = 0; y < height; y ++) {
        for (int x = 0; x < width; x ++) {
            if (change[y][x] != null && change[y][x].substring(0,1).equals("B"))
                continue;
            else {
                change[y][x] = "" + spotCheck(change, x, y, width, height) + "H";
            }
        }
    }
    return change;
}

}

  • 3
    Please create a proper [mcve], show us your code (as code, not image, please). – Zabuzard Mar 10 '18 at 02:21
  • Can you post the whole's program's code directly into the question, instead of posting the image of a certain part? – Krishnanshu Gupta Mar 10 '18 at 02:27
  • Try to use the println() method to print text, everytime you go into a new method, to make sure that the method is actually being called or not – Krishnanshu Gupta Mar 10 '18 at 02:29
  • At this point the best I can say is that for some reason your methods aren't being called, there's some sort of implementation error, and your buttons aren't appearing. However, since the panel is basically invisible, it might actually show up, try to change the background color to test this. Let me know, if these tips work or not. – Krishnanshu Gupta Mar 10 '18 at 02:32
  • Also, just for clarification, when you receive the JButton that createGameButton() returns are you actually adding it to the JPanel – Krishnanshu Gupta Mar 10 '18 at 02:34
  • I have added println statements, and every method is in fact being called. I also have tried changing the background color of the panel, and the color of the panel does not change, presumably because it is so transparent, however I am not sure why the background color is not changing. – George Croft Mar 10 '18 at 02:38
  • Yes, I loop through an array of JButtons and add each of them to the JPanel. – George Croft Mar 10 '18 at 02:39
  • Have you checked if you're actually adding the button to your panel, and the panel to your jframe, that is a common mistake for programmers, but without the full code, these are all the tips I can give you. – Krishnanshu Gupta Mar 10 '18 at 02:39
  • How did you try the panel's background color, because setBackground(color of choice) ASSIGNS the color to the panel, but to actually see a difference, the panel's paintComponent() will have to be called. – Krishnanshu Gupta Mar 10 '18 at 02:43
  • I think I've added the buttons to the panel, and the panel to the JFrame, I have included the full code along with the post. – George Croft Mar 10 '18 at 02:43
  • You never add the panel to your frame – Krishnanshu Gupta Mar 10 '18 at 02:49
  • I used setBackground, however I don't understand how to use paintComponent, even after checking the JavaDocs – George Croft Mar 10 '18 at 02:50
  • What aspect of it do you not understand? The one I can think of is calling it, to do simply put repaint() in any non-static method. To implement it, you should probably extend JPanel and put the method and upon calling repaint() it should automatically run. – Krishnanshu Gupta Mar 10 '18 at 02:53

2 Answers2

4

about the nature of JFrame and under what conditions it would be an empty screen like this"

  • You've not added anything to the window
  • You've made the window visible before any components are added to it and failed to call revalidate and repaint on the contentPane (or other child containers)
  • You've removed/added components without calling revalidate and repaint on the affected containers
  • You're blocking the Event Dispatching Thread with some long running or blocking operation preventing from been able to paint/update the UI
  • You've performed some level of custom painting and broken the paint chain in the progress

At a series of guesses

Update based on additional code...

Based on the available information...

public MineSweeperVisual(int height2, int width2, int bombs) {
    height = height2;
    width = width2;
    buttons = new JButton[height * width];
    flag = false;
    result = new JLabel("Playing");

    grid = new String[height][width];
    for (int i = 0; i < bombs; i++) {
        int x = (int) (Math.random()*width);
        int y = (int) (Math.random()*height);
        grid[y][x] = "BH";
    }
    grid = resetGrid(grid, height, width);

    loadButtons();
    createFlagButton();
    createPanel();

    setSize(20 * width, 20 * height);
    setLocationRelativeTo(null);
}

public void createPanel() {
    panel = new JPanel();
    for(JButton i: buttons)
        panel.add(i);
    panel.add(flagButton);
    panel.add(result);
    setBackground(Color.BLACK);
}

panel is never added to the frame

So, after making a number modifications to get the code to run, I added the panel to the contentPane of the JFrame and, instead of setSize, called pack (because it didn't layout out properly on my PC)

Example

public MineSweeperVisual(int height2, int width2, int bombs) {
    height = height2;
    width = width2;
    buttons = new JButton[height * width];
    flag = false;
    result = new JLabel("Playing");

    grid = new String[height][width];
    for (int y = 0; y < height; y++) { 
        for (int x = 0; x < width; x++) { 
            grid[x][y] = "AA";
        }
    }
    for (int i = 0; i < bombs; i++) {
        int x = (int) (Math.random() * width);
        int y = (int) (Math.random() * height);
        grid[y][x] = "BH";
    }
 //     grid = resetGrid(grid, height, width);

    loadButtons();
    createFlagButton();
    createPanel();

    add(panel);
    pack();
    //setSize(20 * width, 20 * height);
    setLocationRelativeTo(null);
}

This suggests to me that you might need to take a closer look at Laying Out Components Within a Container

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

You never added your panel to your frame. Since you have already extended JPanel, just set up everything and right before making the frame visible, add the panel to the frame. Otherwise, you have also created a JFrame, which isn't necessary, as you already extended it, remove one or the other, and just do the same process. Your code should work after that.

  • Is there anything else you need help with? – Krishnanshu Gupta Mar 10 '18 at 02:55
  • Yes actually, sorry to bother you again, is there any way to set the text on a button, after you click on it? For example, a button says "five", and when you click it, it now says "four", – George Croft Mar 10 '18 at 03:25
  • @GeorgeCroft In the `ActionListener`, simply call `setText` on the button. If you don't have access to the button directly, you can get access to it via the `ActionEvent#getSource` method, but you'll have to cast it to a `JButton` as the source is passed in as a `Object` – MadProgrammer Mar 10 '18 at 22:59
  • Sorry about that, for more reference @GeorgeCroft, you can visit this old StackOverflow thread, the top answer should be a great tool for you: https://stackoverflow.com/questions/9412620/changing-a-jbutton-text-when-clicked – Krishnanshu Gupta Mar 10 '18 at 23:47