Shaun Wild
Shaun Wild

Reputation: 1243

JFrame.setExtendedState doesn't actually maximise

public static void main(String args[]){
    JFrame frame = new JFrame();
    frame.setExtendedState(JFrame.MAXIMISED_BOTH);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

I've used this code to maximise a JFrame, but instead of actually maximising the frame, it just sets the window size to that of the screen, without actually changing the state, so clicking the maximize button doesn't actually downscale it again.

Am I using the wrong command or something?

Upvotes: 3

Views: 15556

Answers (8)

Mike Nakis
Mike Nakis

Reputation: 61993

Seven years late is better than never, right?

The question does not provide an SSCCE presumably because this is not all of the code involved. The tiny fragment of code provided work as it is, so practically all previous answers are saying "works for me". So, the problem certainly lies with the rest of the code, which is not shown.

We cannot be sure what the rest of the code does, but I suspect that it tries to persist the state and bounds of the frame, and to restore that state and bounds later, and that is what fails. The OP did not receive an answer 7 years ago because they did not explain what the actual problem was, but this question will be viewed by many more, so here it goes:

In theory, persisting the state and bounds of a frame should be piece of cake, but in practice it is not.

This is a very common problem in GUI applications, and it is basically due to a common mistake on behalf of the programmer. However, it should be noted that various widely used GUI frameworks (and certainly both Swing and SWT in the Java world) operate in a specific perverse way which makes it a very easy mistake to make.

The problem begins with the fact that these frameworks do not support a 'maximized' event, (duh!) so the only way you can detect that your frame has been maximized is to listen to the 'resized' event. So, you are presumably persisting the state and dimensions of your frame from within your 'resized' event handler.

The problem is further compounded by the fact that once the 'resized' event has occurred as a result of maximizing the frame, the frame bounds are the maximized bounds of your frame, which are irrelevant, and you will be shooting yourself in the foot if you make the mistake of persisting them.

So, the solution is to manually keep track of the "normal state" bounds of your frame, and only persist those. This can be accomplished as follows:

    addComponentListener( new ComponentAdapter()
    {
        @Override public void componentResized( ComponentEvent e )
        {
            if( (getExtendedState() & MAXIMIZED_HORIZ) == 0 )
                normalStateBounds.width = getWidth();
            if( (getExtendedState() & MAXIMIZED_VERT) == 0 )
                normalStateBounds.height = getHeight();
            stateAndOrSizeChanged();
        }
        @Override public void componentMoved( ComponentEvent e )
        {
            if( (getExtendedState() & MAXIMIZED_HORIZ) == 0 )
                normalStateBounds.x = getX();
            if( (getExtendedState() & MAXIMIZED_VERT) == 0 )
                normalStateBounds.y = getY();
            stateAndOrSizeChanged();
        }
    } );

...where:

  • normalStateBounds is defined as private final Rectangle normalStateBounds = new Rectangle(); and contains the bounds of your component when in the "normal" (i.e. not minimized, nor maximized) state

  • stateAndOrSizeChanged() is your function which handles persisting the state and bounds of your frame, being careful to only persist normalStateBounds instead of the values returned by getX(), getY(), getWidth(), and getHeight().

When loading the state and bounds from persistence, you can simply invoke setBounds() followed by setExtendedState(), and you should do that before invoking setVisible( true ) to avoid the possibility of your frame appearing restored for a blink of an eye before maximizing. The call to setBounds() will set the non-maximized bounds, and the call to setExtendedState() might maximize your frame, but if you then restore it, it will assume the non-maximized bounds that you have set.

Upvotes: 1

Dharmendrasinh Chudasama
Dharmendrasinh Chudasama

Reputation: 1117

You should use this when applying changes

frame.setResizable(true);

Upvotes: 0

Jesus Flores
Jesus Flores

Reputation: 640

You have an error in frame.setExtendedState(JFrame.MAXIMISED_BOTH);

You should write frame.setExtendedState(JFrame.MAXIMIZED_BOTH); instead

Upvotes: 4

Ajith Moni
Ajith Moni

Reputation: 31

This worked for me:

We need to combine the setSize () and setExtendedState together JFrame frame=new JFrame();

frame.setExtendedState(JFrame.MAXIMIZED_BOTH); // aligns itself with windows task bar
// set maximum screen   
frame.setSize((int)Toolkit.getDefaultToolkit().getScreenSize().getWidth(), (int)Toolkit.getDefaultToolkit().getScreenSize().getHeight());

Upvotes: 1

WeaponsGrade
WeaponsGrade

Reputation: 878

You must want it maximized by default. Because the maximize button works out-of-the-box.

frame.setExtendedState(JFrame.MAXIMIZED_BOTH) works on Linux x64. Here's the program I tested with:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test implements ActionListener {

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

  private JFrame frame;

  public Test() {
    frame = new JFrame();
    frame.add(new JLabel("Hi!"), BorderLayout.CENTER);
    JButton button = new JButton("maximize");
    button.addActionListener(this);
    frame.add(button, BorderLayout.SOUTH);
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
  }


  @Override
  public void actionPerformed(ActionEvent e) {
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
  }
}

Upvotes: 0

MadProgrammer
MadProgrammer

Reputation: 347204

Based on your provided example and run on Windows 7...

"Maximised" state (this is cropped version of window as the original is quite large)

enter image description here

"Normal" state

enter image description here

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ExtendedFrame {

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

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

                JFrame frame = new JFrame();
//                frame.setExtendedState(JFrame.MAXIMISED_BOTH);
                frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

Upvotes: 0

splungebob
splungebob

Reputation: 5415

It works for me running Java 7 on a WinXP machine.

For the record, this is what an SSCCE should look like:

import javax.swing.*;

public class JFrameExtendedDemo
{
  public static void main(String[] args)
  {
    SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(300, 200);
        f.setLocationRelativeTo(null);
        f.setVisible(true);

        // Then:
        f.setExtendedState(JFrame.MAXIMIZED_BOTH);
      }
    });
  }
}

Upvotes: -1

Martijn Courteaux
Martijn Courteaux

Reputation: 68847

Have you tried this?

f.setExtendedState(f.getExtendedState() | JFrame.MAXIMIZED_BOTH);

Upvotes: 0

Related Questions