Swing GUI'leri en iyi şekilde nasıl konumlandırılır?


126

Başka bir ileti dizisinde şöyle bir şey yaparak GUI'lerimi ortalamayı sevdiğimi belirttim:

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

Ancak Andrew Thompson'ın farklı bir fikri vardı.

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

ve sorgulayan beyinler nedenini bilmek ister?


GUI, geçen sefer bittiği yerden başlamalıdır.
NomadMaker

Yanıtlar:


167

Gözüme, ekranın ortasındaki bir GUI çok .. "açılış ekranı" gibi görünüyor. Onların kaybolmasını ve gerçek GUI'nin görünmesini bekliyorum!

Java 1.5'ten beri erişimimiz var Window.setLocationByPlatform(boolean). hangi..

Bu Pencerenin yerel pencere sistemi için varsayılan konumda mı yoksa Pencere bir sonraki görünür hale getirildiğinde geçerli konumda mı (getLocation tarafından döndürülür) görünmesi gerektiğini ayarlar. Bu davranış, konumunu programlı olarak ayarlamadan gösterilen yerel bir pencereye benzer. Çoğu pencereleme sistemi, konumları açıkça ayarlanmadıysa pencereleri basamaklandırır. Gerçek konum, pencere ekranda gösterildiğinde belirlenir.

3 GUI'yi işletim sistemi tarafından seçilen varsayılan konumlara yerleştiren bu örneğin etkisine bir göz atın - Windows 7, Linux ve Gnome ve Mac OS X'te.

Windows 7'de yığılmış pencereler görüntü açıklamasını buraya girin Mac OS X'te yığılmış pencereler

(3 lot) 3 GUI düzgün bir şekilde istiflenmiş. Bu, son kullanıcı için 'en az şaşırtan yolu' temsil eder, çünkü işletim sistemi varsayılan düz metin düzenleyicinin 3 örneğini (veya bu konuda başka herhangi bir şeyi) nasıl konumlandırabilir. Linux ve Mac için trashgod'a teşekkürler. Görüntüler.

İşte kullanılan basit kod:

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 Sayaç değişkeniniz neden iisadece değil i? Bu bir geleneğe uyuyor mu yoksa kişisel bir tercih mi (veya belki tamamen farklı bir şey)?
MirroredFate

1
@MirroredFate Umm .. Sanırım 3. seçeneği orada kilitleyeceğim, "tamamen farklı bir şey". Temelde ilk programladığımda alıştığım şey buydu (evet, uzun zaman önce). Tembellik, sürekli kullanımın nedeni, 'kırılmadıysa, tamir etmeyin'.
Andrew Thompson

1
@MirroredFate Eğer Pers Prensi Fan tarafından şansınız var mı? Buraya koyduğum için çok üzgünüm. Sadece could not resist
Anarach

11
@MirroredFate İşte iibunun yerine kullanıyorum i. Ben yarışmalara programlama katılmak zaman, sık sık diyelim ki, döngü indeksi aramak zorunda, +1ya da -1ondan bir hataları kapalı düzeltmek için. Bu gibi durumlarda, hangi düzenleyiciyi kullandığımdan bağımsız olarak , aramak, aramaktan iiçok daha kolaydır i. Benzer şekilde, kullandığım jjve kkiç içe döngü indeksleri için. :)
musically_ut

5

setLocationByPlatform(true)Yeni bir JFrame'in konumunu belirlemenin en güzel yolu olduğuna tamamen katılıyorum, ancak çift ​​monitör kurulumunda sorunlara girebilirsiniz. Benim durumumda, çocuk JFrame 'diğer' monitörde ortaya çıktı. Örnek: Ekran 2'de ana GUI'm var, ile yeni bir JFrame setLocationByPlatform(true)başlatıyorum ve Ekran 1'de açılıyor. İşte burada daha eksiksiz bir çözüm, sanırım:

...
// 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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.