JFrame (extended) state, iconified/maximized/normal question
There have been a few posts on this in the past but I was unable to find a complete solution
This is a doosy!
I am trying to preserve(store) the frame window NORMAL size and position so that it can be re-instated the next time the application is run.
I am using ComponentListeners to monitor move and resize events and capture and save the window bounds with getBounds() in those events.
When my app exits I save the last captured window bounds, next time it runs I load the window bounds and call setBounds(..) to restore the last window position.
I also save and restore the getExtendedState() to restore the NORMAL, or MAXIMIZED window
One exception is that I do not want to capture and store the window bounds when the window is MAXIMIZED! This would result in my application re-instating the maximum window position and dimensions next time it runs when what I want is the NORMAL position and dimensions.
So in the event listeners I check to see if the getExtendedState() is MAXIMIZED_BOTH and if so I do not store the bounds. (I have also tried the reverse of this, only storing bounds when getExtendedState() is NORMAL)
That's the intuitive way to do it, that's the way all the previous posts indicated to go, but it does not work!
The problem is that the events are queued and by the time they are dispatched by AWT and I query the window with getBounds() I get unpredictable results...
sometimes I get NORMAL window bounds , a Rectangle(100,50,650,400)
sometimes I get partially MAXIMIZED window bounds, Rectangle(-4,-4,650,400)
and sometimes I get fully MAXIMIZED window bounds Rectangle(-4,-4,1024,768)
The reason (I think) is that depending on how much time elapses between the event being queued, dispatched and my listener eventually being called .... the actual frame window may be in a NORMAL position 10,50,640,400 if the timing was fast, may be partly maximized where it has been moved to position -4,-4 but still retains its NORMAL size of 650,400 if the timing was medium or may be fully maximized in position -4,-4 with max width and height of 1024,768 if the timing was slow!
I need a way to get an event that contains both the window state NORMAL/MIN/MAX and that contains window bounds all in one event without having to query the frame for these values?
Or
I need to be able to ignore the events that have partially MAXIMIZED data. I have attempted this but getExtendedState() does not always return MAXIMIZED, sometimes it returns NORMAL even though partial window movement has occurred and is why I end up storing partial data.
this code outputs the getBounds() and window state data in various events and is followed by the output
...
addWindowStateListener(new WindowAdapter(){
publicvoid windowStateChanged(WindowEvent e){
if (e.getNewState()==Frame.MAXIMIZED_BOTH){
// For information purposes only
System.out.println("IN windowStateChanged state=" + extendedStateToString(e.getNewState()));
}
}
});
// Add listener for frame resize events to persist the users curent window size preferences
addComponentListener(new ComponentAdapter(){
publicvoid componentMoved(ComponentEvent e){
// This is where I would store the window bounds if the window was in NORMAL state
System.out.println("IN componentMoved getBounds()= " + getBounds() +", getExtendedState()=" + extendedStateToString(getExtendedState()));
}
publicvoid componentResized(ComponentEvent e){
// This is where I would store the window bounds if the window was in NORMAL state
System.out.println("IN componentResized getBounds()= " + getBounds() +", getExtendedState()=" + extendedStateToString(getExtendedState()));
}
});
...
public String extendedStateToString(int state){
switch (state){
case Frame.MAXIMIZED_BOTH:
return"MAXIMIZED_BOTH";
case Frame.MAXIMIZED_HORIZ:
return"MAXIMIZED_HORIZ";
case Frame.MAXIMIZED_VERT:
return"MAXIMIZED_VERT";
case Frame.NORMAL:
return"NORMAL";
}
return"unknown";
}
Sample output
Notice the first component moved event reports normal window bounds and state = NORMAL, The results of me moving the window. Prefect! I would store this value as the new window position and size
IN componentMoved getBounds()= java.awt.Rectangle[x=953,y=8,width=724,height=425], getExtendedState()=NORMAL
Then notice the component moved event a reports a partially maximized window bounds -4,-4 nut same size as above and worse of all window state still NORMAL! ARggh... I don't want to store this but the window state still reports NORMAL and the data would be saved
IN componentMoved getBounds()= java.awt.Rectangle[x=-4,y=-4,width=724,height=425], getExtendedState()=NORMAL
Now we get a state changed event
IN windowStateChanged state=MAXIMIZED_BOTH
Followed by a resized event reporting maximized window bounds and MAXIMIZED state, this is OK cause I would filter out this event as has a state of MAXIMIZED!
IN componentResized getBounds()= java.awt.Rectangle[x=-4,y=-4,width=1688,height=1058], getExtendedState()=MAXIMIZED_BOTH

