Why is my JFrame window doing that?(check description)

115 views Asked by At

I'm programming a cookie clicker game remake and when I scale the JFrame window, something white appears. It disappears as soon as you hover the cursor over the button(when refreshes) and I need to fix that, because it does even the same when you launch the game.

Here's a screenshot(UNSCALED | SCALED): http://s3.postimg.org/xomifomhf/bandicam_19.png

this is the whole code of this game:

package cookieclicker.tominocz;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main {

    public static int num1;

    static Icon icon1 = new ImageIcon("cookie.png");
    static JButton b1 = new JButton(icon1);
    static JButton b2 = new JButton("You got " + num1 + " Cookies!");

    @SuppressWarnings("serial")
    public static void main(String[] args) {

        File save = new File(".\\gamesave.cookieclicker");
        if (save.exists()) {
            loadGame();
        }

        JFrame f = new JFrame("Cookie Clicker Beta v0.1");
        b2.setBackground(Color.cyan);
        b2.setPreferredSize(new Dimension(10000, 14));

        JPanel buttonPanel1 = new JPanel(new GridLayout(1, 1));
        buttonPanel1.setBackground(Color.DARK_GRAY);
        b2.setEnabled(false);
        b2.setBorder(null);
        buttonPanel1.add(b2);

        JPanel buttonPanel2 = new JPanel(new GridLayout(1000, 1));
        buttonPanel2.setBackground(Color.DARK_GRAY);
        buttonPanel2.setEnabled(false);
        buttonPanel2.add(new JButton("Grandma"));
        buttonPanel2.add(new JButton(""));
        buttonPanel2.add(new JButton(""));

        JPanel east = new JPanel(new GridBagLayout());
        JPanel north = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.NORTH;
        gbc.weighty = 1;

        north.add(buttonPanel1, gbc);
        east.add(buttonPanel2, gbc);

        JPanel center = new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
        };
        center.setBorder(BorderFactory.createLineBorder(Color.BLACK));

        f.add(east, BorderLayout.EAST);
        f.add(north, BorderLayout.NORTH);
        f.add(center);

        f.pack();

        f.setSize(600, 400);
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        b1.setBackground(Color.lightGray);
        b1.setBorder(null);
        f.add(b1);
        b1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Object source = e.getSource();
                if (source instanceof JButton) {
                    addCookies();
                }
            }
        });
    }

    public static void addCookies() {

        saveGame();

        b2.setText("You got " + ++num1 + " Cookies!");

        if (num1 == 1) {
            b2.setText(" You got " + 1 + " Cookie! ");
        } else {
            b2.setText("You got " + num1 + " Cookies!");
        }
        System.out.println(num1);
    }

    public static void saveGame() {
        try {

            BufferedWriter writer = new BufferedWriter(new FileWriter(
                    ".\\gamesave.cookieclicker"));
            writer.write(String.valueOf(1 + num1));

            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void loadGame() {
        try (BufferedReader br = new BufferedReader(new FileReader(
                ".\\gamesave.cookieclicker"))) {
            String SavedGame;

            while ((SavedGame = br.readLine()) != null) {
                num1 = Integer.parseInt(SavedGame);
                b2.setText("You got " + num1 + " Cookies!");
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

And also the other thing is, that the dark grey strip is hiding 3 buttons. Don't count the 4th one, that's the one showing the ammount of cookies you have :).

Now where could the problem be?

2

There are 2 answers

0
MadProgrammer On

You have two components sharing the CENTRE position of the frame's BorderLayout, center and b1.

b1, been the last component added, is getting the attention of the layout manager and is been laid out when the frame is resized, center is not and is remaining at the last size/position it was set to (because you called pack, which forced the frame to layout it's child components, but then you added b1 after it).

BorderLayout can only manage a single component at each of it's five pre-defined positions

Make a decision about who should be in the centre...

You should also have a read of Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? and stop messing with the preferred size of your components, let them make their own decisions in combination with appropriate layout managers

I'd also encourage you to move the content of your main method some where else (may be the class's constructor), this way, you fields won't need to be static and it solve a ton of other issues you might have in the future

1
camickr On

First of all:

b2.setPreferredSize(new Dimension(10000, 14));

Don't specify preferred sizes for components. Each component is responsible for determining its own preferred size. Let the layout manager determine the size.

JPanel buttonPanel2 = new JPanel(new GridLayout(1000, 1));

Don't use random numbers when defining the GridLayout. If you want one column then just use: new GridLayout(0, 1). Now all components added will be displayed in the first row.

Now for your problem:

f.add(center);
f.pack();

You add an empty panel to the CENTER of the BorderLayout. Then you pack the frame so the panel now has a valid size.

f.add(b1);

But then you add a second component to the "CENTER". However BorderLayout will only manage the size of the last component added.

Swing will paint() the last component added first, so the button is painted, then the panel is painted over top of it.

If you move the mouse over the center, then the mouse event is passed to the button and the rollover logic is invoked so the button is painted.

If you resize the frame, the buttons size is recalculated by the layout manager and components are repainted. Again, the center panel is painted last so you see part of the button with the panel on top.

I don't know why you have the center panel so I can't make a specific suggestion other than to say, get rid of it. Again the main problem is you are trying to add two components to the center. Don't do this!