1

I am writing an a snake game, but there's a small problem. SOMETIMES there's a little gap between the panel and the frame. I really have no idea what could be the problem as it appears so irregularly.

The gap is on the right and bottom. This time, it is displayed correctly. SSCCE:

public class Game {

static JFrame frame = new JFrame("The Snake Game");
static Game game = new Game();
JPanel cards;
static JPanel card1 = new JPanel();

private Game() {    
}

public void addComponentToPane(Container pane) {

    // CARD 1

    card1.setLayout(null);
    card1.setPreferredSize(new Dimension(600, 625));        

    CardLayout cl = new CardLayout();        
    cards = new JPanel(cl);
    cards.add(card1);

    pane.add(cards, BorderLayout.CENTER);
}

private static void createAndShowGUI() {

    game.addComponentToPane(frame.getContentPane());
    frame.setResizable(false);      
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.pack();

    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

} 

public static void main(String[] args) {

        javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });

} // end of main

}

tshepang
  • 12,111
  • 21
  • 91
  • 136
Kuba Spatny
  • 26,618
  • 9
  • 40
  • 63
  • Well...first of all, you are not using `CardLayout` correctly. – Branislav Lazic May 03 '13 at 21:41
  • Umm, what is the correct use then? – Kuba Spatny May 03 '13 at 21:44
  • `SOMETIMES there's a little gap between the panel and the frame. ` - make sure the code to create the GUI executes on the EDT. Also, don't use static variables. – camickr May 03 '13 at 21:45
  • @camickr - it does, I just din't include it here to make it shorter. :) – Kuba Spatny May 03 '13 at 21:48
  • 1
    Create an instance of CardLayout: `CardLayout cl = new CardLayout();` Pass that instance in `setLayout(cl)` method. Add additional containers (card1,card2) like this: `cards.add(card1,"card1");`. To show desired `JPanel`: `cl.show(cards,"card1");` (To show card1 `JPanel`). – Branislav Lazic May 03 '13 at 21:49
  • Post a SSCCE that demonstrates the problem. We don't want to waste time guessing what you may or may not be doing. So post the version that shows you are using the EDT so we can make sure you are doing it correctly. As demonstrated by the above usage of CardLayout. You thought you were using it correctly but you are not. Also, you have not posted a SSCCE since we don't know what the DB class is. – camickr May 03 '13 at 21:49
  • @brano88 - I don't see that big of a difference. Why is it important to pass that instance in `setLayout()` and not just do `setLayout(new CardLayout)`? Plus this is from Java Tutorials: `cards = new JPanel(new CardLayout()); cards.add(card1, BUTTONPANEL);` [link](http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/layout/CardLayoutDemoProject/src/layout/CardLayoutDemo.java) – Kuba Spatny May 03 '13 at 22:03
  • @camickr - Okay, edited. Sorry about the DB class, i didn't notice it was mentioned, but the problem persists even though it's not used/added. – Kuba Spatny May 03 '13 at 22:04
  • I think that JComponents added to CardLayout & JTabbedPane placed to JFrame by default automatically fills all available Dimmansion, correct me someone if I'm wrong, – mKorbel May 03 '13 at 22:07
  • this code works correctly, and nothing, somewhere, somehow touched described issue, issue can came from backgroung image, override getPreferredSize for JPanel, – mKorbel May 03 '13 at 22:09
  • @mKorbel - the issue is there even when using just the code mentioned above. I have to open 2-10 windows to get the problem. – Kuba Spatny May 03 '13 at 22:19
  • I have to open 2-10 windows to get the problem. windows are JFrames, or windows are Cards added to CardLayout, I don't believe, remove all setPreferredSize and to override getPreferredSize for JPanel, then pack() returns to JFrame the same Dimension, but nothing special is calling pack() after card switched, sure in the case that each of cards has different PreferrredSize – mKorbel May 03 '13 at 22:26
  • @mKorbel 10 times run the app, thus 10 JFrames. – Kuba Spatny May 03 '13 at 22:29
  • :-) .............., no idea whats happened, until this moment I was sure – mKorbel May 03 '13 at 22:34
  • @mKorbel - did you manage to get the problem? – Kuba Spatny May 03 '13 at 22:42
  • The posted code still uses the DB class and doesn't execute on the EDT. – camickr May 04 '13 at 00:47
  • @camickr - Are you sure you refreshed the page? Because I deleted adding second card which used the DB class completely and added the EDT. – Kuba Spatny May 04 '13 at 07:16

3 Answers3

2

Try calling setResizable AFTER you call pack

For some reason, doing it the other way seems to add about 10-20 pixels to the width and height.

If that doesn't work, call setResizable AFTER the frame has being made visible

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I've just tried every single combination of calling `setResizable` - none of it works. However, it works perfectly when `setResizable` is not used at all. – Kuba Spatny May 03 '13 at 22:58
1

I encounter the same problem today. After a little bit of Googling, I couldn't find any good answer. Kuba gave a good hint and the problem is finally resolved. I guess this issue is caused by the delay of the setResizable(false) function and hence it happens occasionally. My solution is adding a short hold after calling setResizable.

setResizable(false);
try {
    Thread.sleep(200);
} catch (InterruptedException e) {
    e.printStackTrace();
}
Vapto
  • 11
  • 1
0

Okay, I know this is a disgusting way to do it. But in the question JFrame isResizable(false) sizing issue is said: "You can reset it by call JFrame#pack after the calling JFrame#setResizable". So I thought, why not reset it twice?!

Code:

private static void createAndShowGUI() {

  game.addComponentToPane(frame.getContentPane());
  frame.setResizable(false);      
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  frame.pack();

  if(frame.getContentPane().getWidth() > 600){
        frame.pack();
  }

  frame.setLocationRelativeTo(null);
  frame.setVisible(true);
}

So calling the method pack() for the second time when the width is greater than my preferred size seems to resolve the problem.

Community
  • 1
  • 1
Kuba Spatny
  • 26,618
  • 9
  • 40
  • 63