如何最好地定位 Swing GUI?

2022-08-31 08:28:50

在另一个线程中,我说我喜欢通过做这样的事情来使我的GUI居中:

JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new HexagonGrid());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

但安德鲁·汤普森有不同的看法,转而打电话给

frame.pack();
frame.setLocationByPlatform(true);

好奇的头脑想知道为什么吗?


答案 1

在我看来,屏幕中间的GUI看起来如此。“初始屏幕”。我一直在等待它们消失,真正的GUI出现!

从Java 1.5开始,我们可以访问Window.setLocationByPlatform(boolean)。哪。。

设置下次使窗口可见时,此窗口是应出现在本机窗口系统的默认位置,还是应显示在当前位置(由 getLocation 返回)。此行为类似于在不以编程方式设置其位置的情况下显示的本机窗口。大多数窗口系统在窗口位置未明确设置时会层叠窗口。一旦窗口显示在屏幕上,就会确定实际位置。

看看这个例子的效果,它将3个GUI放在操作系统选择的默认位置 - 在Windows 7,Linux与Gnome和Mac OS X上。

Stacked windows on Windows 7enter image description hereStacked windows on Mac OS X

(3 批)3 个 GUI 整齐堆叠。这代表了最终用户的“最不令人惊讶的路径”,因为这是操作系统可能放置默认纯文本编辑器(或其他任何内容)的3个实例的方式。我感谢垃圾神的Linux和Mac图像。

下面是使用的简单代码:

import javax.swing.*;

class WhereToPutTheGui {

    public static void initGui() {
        for (int ii=1; ii<4; ii++) {
            JFrame f = new JFrame("Frame " + ii);
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            String s =
                "os.name: " + System.getProperty("os.name") +
                "\nos.version: " + System.getProperty("os.version");
            f.add(new JTextArea(s,3,28));  // suggest a size
            f.pack();
            // Let the OS handle the positioning!
            f.setLocationByPlatform(true);
            f.setVisible(true);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater( new Runnable() {
            public void run() {
                try {
                    UIManager.setLookAndFeel(
                        UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {}
                initGui();
            }
        });
    }
}

答案 2

我完全同意这是指定新JFrame位置的最佳方法,但在双显示器设置上,您可能会遇到问题。在我的例子中,子JFrame在“另一个”监视器上生成。示例:我在屏幕2上有我的主GUI,我启动了一个新的JFrame,它在屏幕1上打开。所以这里有一个更完整的解决方案,我认为:setLocationByPlatform(true)setLocationByPlatform(true)

...
// Let the OS try to handle the positioning!
f.setLocationByPlatform(true);
if (!f.getBounds().intersects(MyApp.getMainFrame().getBounds())) {
    // non-cascading, but centered on the Main GUI
    f.setLocationRelativeTo(MyApp.getMainFrame()); 
}
f.setVisible(true);

推荐