简体   繁体   中英

Java un-maximize JFrame

I have a simple question that I have not found an answer two, possibly because I do not know how to title it. Lets say I have a JFrame with width X and height Y. Somewhere in my program I must maximize it to fit to take up the whole screen, and do myJFrame.setExtendedState(JFrame.MAXIMIZED_BOTH); to accomplish that. Now, somewhere later I must make the JFrame "un-maximize" and return to its original size. There is probably a simple command for this but i have not found any. I have in mind a command akin to something like myJFrame.setExtendedState(JFrame.MAXIMIZED_NONE); So in short: after maximizing a JFrame, how do I "un-maximize" it?

Edit: It seems that the problem was not that i was not able to find the method i neaded, but that some of my code was preventing myJFrame.setExtendedState(JFrame.NORMAL); from working correctly. Here is this buggy code:

        frame.dispose();
        if (b) {
            frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
            frame.setUndecorated(true);
        } else {
            frame.setExtendedState(JFrame.NORMAL);
            frame.setUndecorated(false);
        }
        frame.setVisible(true);

Rearranging the statements in the above code fixed the problem :)

If you have a look at the JavaDocs for Frame#setExtendedState , you will see a list of possible values

Sets the state of this frame. The state is represented as a bitwise mask.
- NORMAL
Indicates that no state bits are set.
- ICONIFIED
- MAXIMIZED_HORIZ
- MAXIMIZED_VERT
- MAXIMIZED_BOTH
Concatenates MAXIMIZED_HORIZ and MAXIMIZED_VERT.

Then if we have a look at Frame#NORMAL

Frame is in the "normal" state. This symbolic constant names a frame state with all state bits cleared

That seems promising

import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {

            JButton unmax = new JButton("Switch");
            unmax.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JFrame frame = (JFrame) SwingUtilities.windowForComponent(TestPane.this);
                    if (frame.getExtendedState() != JFrame.NORMAL) {
                        frame.setExtendedState(JFrame.NORMAL);
                    } else {
                        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
                    }
                }
            });
            setLayout(new GridBagLayout());
            add(unmax);

        }

    }

}

So, all this does, is checks the current windows extendedState , if it's not set to NORMAL , it sets it to NORMAL , otherwise it sets it to MAXIMIZED_BOTH

Updated based on example code...

Okay, so based on your example code...

frame.dispose();
if (b) {
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    frame.setUndecorated(true);
} else {
    frame.setExtendedState(JFrame.NORMAL);
    frame.setUndecorated(false);
}
frame.setVisible(true);

The problem "seems" to lie with either dispose or setUndecorated or a combination of both. What "seems" to happening is when you restore the frame to it's normal state, it's maintaining the size and position it was when it was maximized.

So, what I did, was grab a copy of the windows bounds before it was maximised and when it was restored, I reapplied it

public class TestPane extends JPanel {

    private Rectangle previousBounds;

    public TestPane() {

        JButton unmax = new JButton("Switch");
        unmax.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFrame frame = (JFrame) SwingUtilities.windowForComponent(TestPane.this);
                frame.dispose();
                if (frame.getExtendedState() != JFrame.NORMAL) {
                    frame.setExtendedState(JFrame.NORMAL);
                    frame.setUndecorated(false);
                    frame.setBounds(previousBounds);
                } else {
                    previousBounds = frame.getBounds();
                    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
                    frame.setUndecorated(true);
                }
                frame.setVisible(true);
            }
        });
        setLayout(new GridBagLayout());
        add(unmax);

    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM