javaswingwindowbuilder

Custom maximize, minimize buttons


I created custom buttons for maximize, minimize and exit. And everything is working, with one exception, program does not remember in which state window was, before minimization. So my question is, is there a way, program to remember window state before minimization, and restore that state, and not to return only on NORMAL state?

My solution for:

maximize:

JButton btnO = new JButton("O");
    btnO.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            if (frame.getExtendedState() == JFrame.MAXIMIZED_BOTH) {
                frame.setExtendedState(JFrame.NORMAL);
            } else {
                frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
            }
        }
    });

and Minimize:

JButton btnMinimize = new JButton("-");
    btnMinimize.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            frame.setExtendedState(JFrame.ICONIFIED);
        }
    });

Solution

  • You can take the ComponentListener approach and restore its state when the component (in your case, the frame), is resized. Some extra comments inside the code.

    Take a look at this example:

    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.event.ComponentEvent;
    import java.awt.event.ComponentListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
    
    public class FrameState extends JFrame {
        private static final long serialVersionUID = 1965751967944243251L;
        private int state = -1; // Variable to keep the last state.
    
        public FrameState() {
            super("Nothing :)");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JButton b = new JButton("-");
            b.addActionListener(e -> {
                state = getExtendedState(); //Store the state before "-" is pressed
                setExtendedState(JFrame.ICONIFIED);
            });
            JButton o = new JButton("O");
            o.addActionListener(e -> {
                if (getExtendedState() == JFrame.MAXIMIZED_BOTH) {
                    setExtendedState(JFrame.NORMAL);
                } else {
                    setExtendedState(JFrame.MAXIMIZED_BOTH);
                }
            });
            getContentPane().setLayout(new FlowLayout());
            getContentPane().add(o);
            getContentPane().add(b);
            setSize(new Dimension(300, 300));
            setLocationRelativeTo(null);
            addComponentListener(new ComponentListener() {
    
                @Override
                public void componentShown(ComponentEvent arg0) {
                }
    
                @Override
                public void componentResized(ComponentEvent arg0) {
                    if (state != -1) {
                        setExtendedState(state); //Restore the state.
                        state = -1; //If it is not back to -1, window won't be resized properly by OS.
                    }
                }
    
                @Override
                public void componentMoved(ComponentEvent arg0) {
                }
    
                @Override
                public void componentHidden(ComponentEvent arg0) {
                }
            });
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> {
                FrameState f = new FrameState();
                f.setVisible(true);
            });
        }
    }