Java 为所有窗口管理器写入正确的JFrames

Java 为所有窗口管理器写入正确的JFrames,java,swing,jframe,window-managers,Java,Swing,Jframe,Window Managers,在Linux(这里是在不同的窗口管理器下)、Mac和Windows上以相同的方式显示JavaJFrame窗口的正确方法是什么 实际上,我们在使用JFrame时遇到了一些问题,这是非常不一致的,因为在Windows上JFrame是最大化的,在我的带有awesome WM的Linux笔记本上,窗口只是打包的,而在Mac下,窗口是半最大化的,因此它比Linux上的窗口大,但没有打包 我们试图将屏幕设置为最大尺寸,这在windows下似乎工作得很好,但在Mac和Linux下却不行(很棒的WM) 下面是一

在Linux(这里是在不同的窗口管理器下)、Mac和Windows上以相同的方式显示Java
JFrame
窗口的正确方法是什么

实际上,我们在使用
JFrame
时遇到了一些问题,这是非常不一致的,因为在Windows上
JFrame
是最大化的,在我的带有awesome WM的Linux笔记本上,窗口只是打包的,而在Mac下,窗口是半最大化的,因此它比Linux上的窗口大,但没有打包

我们试图将屏幕设置为最大尺寸,这在windows下似乎工作得很好,但在Mac和Linux下却不行(很棒的WM)

下面是一个非常简单的框架,它解释了我们目前正在做的事情:

import java.awt.Dimension;
import java.awt.Toolkit;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class JFrameMaximize extends JFrame {
    private static final long serialVersionUID = 1L;

    public JFrameMaximize() {
    setVisible(true);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    JPanel panel = new JPanel();
    // A Fake Dimension, inside this panel are a lot of swing components
    panel.setPreferredSize(new Dimension(333, 666));

    setContentPane(panel);

    // Now we want to set the Extended State
    if (Toolkit.getDefaultToolkit().isFrameStateSupported(MAXIMIZED_BOTH)) {
        setExtendedState(MAXIMIZED_BOTH);
    } else {
        System.out.println("Oh oh... i have a problem...");

        // Now we need a Fullscreen but we dont have the size of a WindowManager Panels and
        // stuff
        Dimension max = Toolkit.getDefaultToolkit().getScreenSize();
        // asume that the screen has a 20px bar on top (=awesome wm)
        max.height -= 20;
        setSize(max);
        setLocation(0, 20);
        // The alternative is to call pack() here, but then the window is totally broken, because of the internal components. Every Panel we load in here has a different size, so the window will scale up and down on every panel change.
    }
    }

    public static void main(String... args) {
    new JFrameMaximize();
    }
}
问题是一些窗口管理器没有最大化扩展状态,所以我们必须计算-这是不可能知道每台电脑! 如何在每个窗口管理器上将窗口设置为正确的大小

唯一的解决方案是固定的默认大小,这是给
JFrame
?尝试最大化窗口?

一些观察结果:

  • 总是从第一天开始

  • 调用
    pack()
    然后调整帧大小,然后执行
    setVisible()

  • 考虑使用:

修订:


请提供一个能显示您描述的问题的列表。@trashgood+1。作为一个附带的评论,你的行为和你描述的一样吗。。问题是我必须在这里粘贴大约3个类…另外,你能回答我的问题吗?@AndrewThompson:作为参考,我在你的应用程序中添加了一个Linux屏幕截图。好的,但是在这种情况下我该怎么做<代码>getMaximumWindowBounds():java.awt.Rectangle[x=0,y=0,width=1280,height=800]getScreenSize():java.awt.Dimension[width=1280,height=800]-我的windowmanager不在乎……哎哟!我在Aqua和GTK+上看到了有用的数字。您的结果听起来像是实现缺陷。在这种情况下,你可能会被一个神奇的数字困住。你能在一些属性上设置它吗,比如
os.name
?我选择检测这些糟糕的窗口管理器:我检查getScreenSize和getMaximumWindowBounds是否给出相同的结果(如果我不能设置扩展状态),然后给窗口指定一个特定的大小。在大多数情况下,这些窗口管理器都有自己的大小调整,或者只是全屏显示应用程序,所以我认为它会工作得足够好…我不知道有什么更好的解决方法。如果您添加了任何新发现的答案,请与我联系。
GraphicsEnvironment env =
    GraphicsEnvironment.getLocalGraphicsEnvironment();
Rectangle bounds = env.getMaximumWindowBounds();
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Toolkit;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class JFrameMaximize extends JFrame {

    public JFrameMaximize() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        // A fake panel representing many swing components
        panel.setPreferredSize(new Dimension(333, 666));
        panel.setBorder(BorderFactory.createLineBorder(Color.blue, 10));
        this.add(panel);
        this.pack();
        // Now we want to set the Extended State, if supported
        if (Toolkit.getDefaultToolkit().isFrameStateSupported(MAXIMIZED_BOTH)) {
            System.out.println("Frame state supported.");
            this.setExtendedState(MAXIMIZED_BOTH);
        } else {
            System.out.println("Frame state not supported.");
            Dimension max = Toolkit.getDefaultToolkit().getScreenSize();
            // TODO see getMaximumWindowBounds()
            max.height -= 20;
            this.setSize(max);
            this.setLocation(0, 20);
        }
        this.setVisible(true);
    }

    public static void main(String... args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new JFrameMaximize();
            }
        });
    }
}