如何最佳定位Swing GUI?


126

另一个线程中,我表示我喜欢通过执行以下操作来居中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);

但是安德鲁·汤普森(Andrew Thompson)有不同的看法,而是打电话给

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

想问的人想知道为什么吗?


gui应该从上次结束的位置开始。
NomadMaker

Answers:


167

在我看来,屏幕中间的一个GUI看起来是这样的。我一直在等待它们消失,真正的 GUI出现!

从Java 1.5开始,我们可以使用Window.setLocationByPlatform(boolean)。哪一个..

设置此窗口是否应在下一次使该窗口可见时显示在本机窗口系统的默认位置还是当前位置(由getLocation返回)。此行为类似于未通过编程设置其位置而显示的本机窗口。如果未明确设置窗口的位置,则大多数窗口系统会级联窗口。一旦窗口显示在屏幕上,便确定了实际位置。

看一下这个示例的效果,该示例将3个GUI设置为操作系统选择的默认位置-在Windows 7,Linux和Gnome和Mac OS X上。

Windows 7上的堆叠式Windows 在此处输入图片说明 Mac OS X上的堆叠式视窗

(3个)3个GUI整齐地堆叠在一起。对于最终用户而言,这代表了“最不惊奇的道路”,因为这是操作系统可能放置默认纯文本编辑器(或其他任何方式)的3个实例的方式。感谢Linux和Mac的rashgod。图片。

这是使用的简单代码:

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

1
@AndrewThompson为什么您的计数器变量ii不仅仅是变量i?是否遵守某些约定还是个人喜好(或可能完全不同)?
MirroredFate 2014年

1
@MirroredFate嗯..我想我将在选项3中锁定“完全不同”。这就是我第一次使用Basic编程时所习惯的(是的,很久以前)。懒惰是继续使用的原因,“如果没有破裂,请不要修复”。
2014年

1
@MirroredFate你是波斯范王子吗?很抱歉把它放在这里。我无法抗拒
Anarach 2015年

11
@MirroredFate这就是为什么我使用ii而不是的原因i。当我参加编程比赛时,我常常不得不搜索循环索引,例如从中检索+1-1从中检索,以解决一个错误。在这些情况下,无论使用什么编辑器,搜索ii都比搜索容易得多i。同样,我将jjkk用于嵌套循环索引。:)
musicly_ut

5

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

...
// 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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.