Как лучше позиционировать Swing GUI? - PullRequest
124 голосов
/ 22 августа 2011

В другой теме Я сказал, что мне нравится центрировать мой графический интерфейс, выполняя что-то вроде этого:

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

и пытливые умы хотят знать, почему?

Ответы [ 2 ]

165 голосов
/ 22 августа 2011

На мой взгляд, графический интерфейс в середине экрана выглядит так .. "splash-screen'ish". Я продолжаю ждать их исчезновения и появления real GUI!

Начиная с Java 1.5 у нас был доступ к Window.setLocationByPlatform(boolean). который ..

Устанавливает, должно ли это окно появляться в расположении по умолчанию для собственной оконной системы или в текущем местоположении (возвращаемом getLocation) при следующем отображении окна. Это поведение напоминает собственное окно, отображаемое без программной установки его местоположения. Большинство оконных систем каскадируют окна, если их местоположение не задано явно. Фактическое местоположение определяется, как только окно отображается на экране.

Посмотрите на эффект этого примера, который устанавливает 3 графических интерфейса в позиции по умолчанию, выбранные ОС - в Windows 7, Linux с Gnome и Mac OS X.

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

(3 лота) 3 аккуратно сложенных графических интерфейса. Это представляет «путь наименьшего удивления» для конечного пользователя, поскольку именно так ОС может расположить 3 экземпляра обычного текстового редактора по умолчанию (или что-нибудь еще, в этом отношении). Я благодарю trashgod за 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();
            }
        });
    }
}
5 голосов
/ 19 сентября 2017

Я полностью согласен с тем, что setLocationByPlatform(true) - это самый хороший способ указать позицию нового JFrame, но при установке с двумя мониторами вы можете столкнуться с проблемами. В моем случае дочерний JFrame появляется на «другом» мониторе. Пример: у меня есть основной графический интерфейс на экране 2, я запускаю новый 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...