简体   繁体   English

JFrame.setExtendedState 实际上并没有最大化

[英]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.我已经使用此代码来最大化 JFrame,但实际上并没有最大化框架,它只是将窗口大小设置为屏幕的大小,而不实际更改状态,因此单击最大化按钮实际上不会再次缩小它。

Am I using the wrong command or something?我使用了错误的命令还是什么?

You have an error in frame.setExtendedState(JFrame.MAXIMISED_BOTH);您在frame.setExtendedState(JFrame.MAXIMISED_BOTH);有错误frame.setExtendedState(JFrame.MAXIMISED_BOTH);

You should write frame.setExtendedState(JFrame.MAXIMIZED_BOTH);你应该写frame.setExtendedState(JFrame.MAXIMIZED_BOTH); instead反而

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. frame.setExtendedState(JFrame.MAXIMIZED_BOTH)适用于 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);
  }
}

你试过这个吗?

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

Based on your provided example and run on Windows 7...根据您提供的示例并在 Windows 7 上运行...

"Maximised" state (this is cropped version of window as the original is quite large) “最大化”状态(这是窗口的裁剪版本,因为原始窗口很大)

在此处输入图片说明

"Normal" state “正常”状态

在此处输入图片说明

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);
            }
        });
    }
}

This worked for me:这对我有用:

We need to combine the setSize () and setExtendedState together JFrame frame=new JFrame();我们需要将 setSize() 和 setExtendedState 组合在一起 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());

您应该在应用更改时使用它

frame.setResizable(true);

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.这个问题可能没有提供SSCCE,因为这不是所涉及的所有代码。 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: OP 7 年前没有收到答案,因为他们没有解释实际问题是什么,但是这个问题会被更多人看到,所以这里是:

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.这是 GUI 应用程序中非常常见的问题,基本上是由于代表程序员的一个常见错误。 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.然而,应该注意的是,各种广泛使用的 GUI 框架(当然还有 Java 世界中的 Swing 和 SWT)以特定的反常方式运行,这使得很容易犯错误。

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(); normalStateBounds定义为private final Rectangle normalStateBounds = new Rectangle(); and contains the bounds of your component when in the "normal" (ie 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() . stateAndOrSizeChanged()是处理保持框架的状态和边界的函数,注意只保持normalStateBounds而不是getX()getY()getWidth()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.从持久性加载状态和边界时,您可以简单地调用setBounds()后跟setExtendedState() ,并且您应该在调用setVisible( true )之前执行此操作,以避免您的帧在最大化之前一眨眼就恢复. 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.setBounds()的调用将设置非最大化边界,而对setExtendedState()的调用可能会最大化您的框架,但如果您随后恢复它,它将假定您已设置的非最大化边界。

It works for me running Java 7 on a WinXP machine.它适用于在 WinXP 机器上运行 Java 7 的我。

For the record, this is what an SSCCE should look like:作为记录,这就是 SSCCE 的样子:

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);
      }
    });
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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