Search code examples
javaswingwindowpersistencejframe

Get Normal JFrame Bounds while Maximized


I am attempting to create a JFrame that remembers its window position, size and whether it was maximized or not. It should be simple enough to use a WindowListener for the windowClosing event and save it's bounds to Preferences.

In order for this to work (as set up below), I would need to extract the JFrame's normal (NORMAL ExtendedState) bounds while it is maximized (MAXIMIZED_BOTH ExtendedState). Is this at all possible? Considering that the normal bounds are stored somewhere in order for it to revert back.

//...
addWindowListener(new WindowListener() {
    ///...
    @Override
    public void windowClosing(WindowEvent e) {
        prefs.putBoolean("win_max",win_max);
        if(winmax)
        {
            //win_x=?
            //win_y=?
            //win_w=?
            //win_h=?
        }
        else
        {
            win_x=getX();
            win_y=getY();
            win_w=getWidth();
            win_h=getHeight();
        }
        prefs.putInt("win_x",win_x);
        prefs.putInt("win_y",win_y);
        prefs.putInt("win_w",win_w);
        prefs.putInt("win_h",win_h);
    }
});
//...

I apologise if this is a really simple question. Any help is appreciated.


Solution

  • Here's what I did. The model instance saved the frame origin, frame bounds, and frame state.

    protected int           state;
    
    protected Point         frameOrigin;
    
    protected Rectangle     frameBounds;
    

    This is a component listener that I created to capture frame data changes.

        frame.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentMoved(ComponentEvent event) {
                if (isMaximized()) {
                    model.setFrameOrigin(frame.getLocation());
                } else {
                    model.setFrameBounds(frame.getBounds());
                }
                model.setFrameState(frame.getExtendedState());
            }
            @Override
            public void componentResized(ComponentEvent event) {
                model.setFrameState(frame.getExtendedState());
            }
        });
    

    This is the code that I had to perform after packing the frame to set the frame to the last used state.

        frame.pack();
        if (options.getFrameBounds().getWidth() > 0) {
            frame.setExtendedState(options.getState());
            if (isMaximized()) {
                frame.setLocation(options.getFrameOrigin());
            } else {
                frame.setBounds(options.getFrameBounds());
            }
        }
        model.setFrameState(frame.getExtendedState());
        model.setFrameBounds(frame.getBounds());
        model.setFrameOrigin(frame.getLocation());
    

    And here's the isMaximized method.

    public boolean isMaximized() {
        return (frame.getExtendedState() & JFrame.MAXIMIZED_BOTH) 
                == JFrame.MAXIMIZED_BOTH;
    }
    

    I saved the frame data in a properties file, but you can save and restore the frame data how you want.