【问题标题】:JFrame.setExtendedState doesn't actually maximiseJFrame.setExtendedState 实际上并没有最大化
【发布时间】:2013-09-23 21:19:22
【问题描述】:
public static void main(String args[]){
    JFrame frame = new JFrame();
    frame.setExtendedState(JFrame.MAXIMISED_BOTH);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

我已使用此代码最大化 JFrame,但实际上并没有最大化框架,它只是将窗口大小设置为屏幕大小,而不实际更改状态,因此单击最大化按钮实际上并没有缩小再来一次。

是我使用了错误的命令还是什么?

【问题讨论】:

  • 这可能是平台问题,您使用的是什么操作系统?也可能有一个setSize 调用干扰进程
  • 它对我有用。为了尽快获得更好的帮助,请发布一个 SSCCE 来说明问题。很多时候,只需创建SSCCE 就会发现问题。
  • 我认为这是一个 SSCCE,我看不出我缺少什么。
  • 阅读我提供的链接,看看SSCCE 到底是什么。
  • 不完全。请看我下面的帖子。它应该是一个完整的、可运行的程序,而不仅仅是一个方法(有错字)。

标签: java swing jframe fullscreen


【解决方案1】:

frame.setExtendedState(JFrame.MAXIMISED_BOTH); 有错误

你应该改写frame.setExtendedState(JFrame.MAXIMIZED_BOTH);

【讨论】:

    【解决方案2】:

    你试过了吗?

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

    【讨论】:

    • 产生的结果与我在问题中描述的结果相同,管道代表什么?
    • 它对左右分量进行按位或。所以,基本上你是在“添加”MAXIMIZED_BOTH 而不是覆盖所有其他状态。
    【解决方案3】:

    基于您提供的示例并在 Windows 7 上运行...

    “最大化”状态(这是窗口的裁剪版本,因为原始窗口很大)

    “正常”状态

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

    【讨论】:

    • 经过一番试验,当我立即执行设置扩展状态时,它会正确地将其设置为最大化状态,但是当我稍后调用它时,它只会调整它的大小。跨度>
    【解决方案4】:

    您必须希望它默认最大化。因为最大化按钮开箱即用。

    frame.setExtendedState(JFrame.MAXIMIZED_BOTH) 适用于 Linux x64。这是我测试过的程序:

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

    【讨论】:

    • 这似乎什么也没做。
    • 我希望它在你的环境中。我编辑了答案以添加我测试过的示例。
    【解决方案5】:

    这对我有用:

    我们需要把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());
    

    【讨论】:

      【解决方案6】:

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

      frame.setResizable(true);
      

      【讨论】:

        【解决方案7】:

        迟到七年总比没有好,对吧?

        这个问题没有提供SSCCE 大概是因为这不是所涉及的所有代码。提供的代码的小片段按原样工作,因此几乎所有以前的答案都在说“对我有用”。所以,问题肯定出在剩下的代码上,没有显示出来。

        我们无法确定其余代码的作用,但我怀疑它会尝试保持帧的状态和边界,并在以后恢复该状态和边界,这就是失败的原因。 OP 7 年前没有收到答案,因为他们没有解释实际问题是什么,但是这个问题会被更多人看到,所以这里是:

        理论上,持久化帧的状态和边界应该是小菜一碟,但实际上并非如此。

        这是GUI应用程序中很常见的问题,基本上是代表程序员的一个常见错误。但是,应该注意的是,各种广泛使用的 GUI 框架(当然还有 Java 世界中的 Swing 和 SWT)以特定的不正当方式运行,这使得它很容易犯错误。

        问题开始于这些框架不支持“最大化”事件(呃!),因此您可以检测到您的框架已被最大化的唯一方法是侦听“调整大小”事件。因此,您可能会在“调整大小”事件处理程序中保留框架的状态和尺寸。

        由于最大化帧而发生“调整大小”事件后,该问题变得更加复杂,帧边界是 最大化的边界你的框架,这些是无关紧要的,如果你错误地坚持它们,你会在自己的脚上开枪。

        因此,解决方案是手动跟踪帧的“正常状态”边界,并仅保留这些边界。这可以通过以下方式完成:

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

        ...哪里:

        • normalStateBounds 定义为 private final Rectangle normalStateBounds = new Rectangle(); 并包含处于“正常”(即未最小化或最大化)状态时组件的边界

        • stateAndOrSizeChanged() 是处理持久化帧的状态和边界的函数,注意只保留normalStateBounds 而不是getX()getY()getWidth()getHeight() 返回的值.

        从持久化加载状态和边界时,您可以简单地调用setBounds(),然后调用setExtendedState(),并且您应该在调用setVisible( true ) 之前执行此操作,以避免您的帧出现在眨眼之间恢复的可能性在最大化之前。对setBounds() 的调用将设置非最大化边界,对setExtendedState() 的调用可能会最大化您的帧,但如果您随后恢复它,它将采用您设置的非最大化边界。

        【讨论】:

          【解决方案8】:

          它适用于我在 WinXP 机器上运行 Java 7。

          为了记录,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);
                }
              });
            }
          }
          

          【讨论】:

          • 只是一个简单的问题:为什么我应该使用 invokeLater 作为从 main 运行它的姿势?
          • 教程开始在这里:Concurrency in Swing
          • 它确实使窗口全屏,它实际上并没有将状态设置为最大化,所以你不能再把它变小而不大惊小怪
          • @ShaunWild “它实际上并没有将状态设置为最大化,所以你不能再把它变小而不大惊小怪”我想你会有详细说明-也许提供一个用例。这在 Windows(和 Linux)上运行良好。你用的是什么平台?
          • @ShaunWild 您应该使用 invokeLater 来启动基于 Swing 的应用程序,因为您需要确保所有 UI 交互都在事件调度线程的上下文中完成。主线程和EDT不是一回事……
          猜你喜欢
          • 2017-01-29
          • 1970-01-01
          • 2011-12-19
          • 1970-01-01
          • 1970-01-01
          • 2019-04-08
          • 1970-01-01
          • 1970-01-01
          • 2018-09-10
          相关资源
          最近更新 更多