I am writing an Applet game, in which I would like the Applet to re-size to fill the browser window. I understand that this is possible to do with HTML, and for now am just assuming that I have an applet which will occasionally have size changes forced upon it.
Using GridBagLayout, I have had trouble with having a LOT of flicker during re-sizes (it appears to be clearing each JPanel during redraw - I already tried overriding each JPanel's update() method). I decided to delay the re-size of my game until after the window's re-size is finished - both to avoid flickering and so I don't have to deal with many rapid and small re-sizes in my game code.
I have working code for this, which I will attach (though slightly simplified) below. However, this only works when the window is stretched larger in both directions. If either width or height shrinks even momentarily, the game immediately collapses into a small square in the top-left corner.
How can I fix this behavior, so the game will continue to work normally, but let the image get temporarily covered during a re-size?
To explain my code, I have a single JPanel containing my entire game layout at position 0,0 in the top GridBagLayout without any weight. I have an empty label (called emptySpace) at position 1,1 with a weight of 1.0 in each direction:
I make the Game window take up the entire space except during re-sizes with the following code:
public class Isometric extends Applet {
//last measured width/height of the applet
public int APPWIDTH;
public int APPHEIGHT;
boolean resizing = false;
int resizeNum = 0;
//Game extends JPanel
Game game;
JPanel window;
JLabel emptySpace;
//one-time startup
public void init(){
APPWIDTH = this.getWidth();
APPHEIGHT = this.getHeight();
addComponents();
//calls checkSize() every 200ms
Timer timer = new Timer();
timer.schedule(new TimerTask(){
public void run(){
checkSize();
}
},200, 200);
}
private void checkSize(){
//if the dimensions have changed since last measured
if(APPWIDTH != this.getWidth() || APPHEIGHT != this.getHeight()){
APPWIDTH = this.getWidth();
APPHEIGHT = this.getHeight();
resizing = true;
}
else if(resizeNum > 2){ //didn't resize in last 400ms
resizing = false;
resizeNum = 0;
resize();
}
if(resizing){
resizeNum++;
}
}
private void resize(){
APPWIDTH = this.getWidth();
APPHEIGHT = this.getHeight();
//set new preferred size of game container
window.setPreferredSize(new Dimension(APPWIDTH, APPHEIGHT));
GridBagConstraints c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 1.0;
c.weighty = 1.0;
this.remove(emptySpace); //remove empty space to allow container to stretch to preferred size
this.add(emptySpace, c); //add empty space again now with zero width/height
validate(); //recalculates everything so changes occur properly
}
private void addComponents(){
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
window = new JPanel();
window.setLayout(new GridBagLayout());
window.setPreferredSize(new Dimension(APPWIDTH, APPHEIGHT));
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.0;
c.weighty = 0.0;
this.add(window,c);
emptySpace = new JLabel();
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 1.0;
c.weighty = 1.0;
this.add(emptySpace, c);
}
//app close
public void destroy(){
System.exit(0);
}
}