Làm thế nào để định vị tốt nhất GUI GUI?


126

Trong một chủ đề khác, tôi đã nói rằng tôi thích tập trung vào GUI của mình bằng cách thực hiện một cái gì đó như thế này:

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

Nhưng Andrew Thompson có ý kiến ​​khác, thay vào đó hãy gọi

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

và tìm hiểu tâm trí muốn biết tại sao?


Gui nên bắt đầu ở cùng một nơi mà nó đã kết thúc lần trước.
NomadMaker

Câu trả lời:


167

Trước mắt tôi, một GUI ở giữa màn hình trông rất .. "màn hình giật gân". Tôi tiếp tục chờ đợi chúng biến mất và GUI thực sự xuất hiện!

Kể từ Java 1.5, chúng tôi đã có quyền truy cập Window.setLocationByPlatform(boolean). mà ..

Đặt xem Cửa sổ này sẽ xuất hiện ở vị trí mặc định cho hệ thống cửa sổ gốc hoặc tại vị trí hiện tại (được trả về bởi getLocation) vào lần tiếp theo Cửa sổ được hiển thị. Hành vi này giống như một cửa sổ gốc được hiển thị mà không lập trình vị trí của nó. Hầu hết các hệ thống cửa sổ xếp tầng cửa sổ nếu vị trí của chúng không được đặt rõ ràng. Vị trí thực tế được xác định khi cửa sổ được hiển thị trên màn hình.

Hãy xem hiệu ứng của ví dụ này để đặt 3 GUI vào các vị trí mặc định mà HĐH đã chọn - trên Windows 7, Linux với Gnome & Mac OS X.

Các cửa sổ xếp chồng lên nhau trên Windows 7 nhập mô tả hình ảnh ở đây Các cửa sổ xếp chồng lên nhau trên Mac OS X

(3 rất nhiều) 3 GUI được xếp ngay ngắn. Điều này thể hiện 'đường dẫn ít bất ngờ nhất' cho người dùng cuối, vì đó là cách hệ điều hành có thể định vị 3 trường hợp của trình soạn thảo văn bản thuần mặc định (hoặc bất cứ điều gì khác, cho vấn đề đó). Tôi cảm ơn thùng rác cho Linux và Mac. hình ảnh.

Đây là mã đơn giản được sử dụng:

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
@AndrewThndry Tại sao bộ đếm của bạn biến iithay vì chỉ i? Điều đó có tuân thủ một số quy ước hay đó là một sở thích cá nhân (hoặc có thể là một cái gì đó hoàn toàn khác)?
MirroredFate

1
@MirroredFate Umm .. Tôi nghĩ rằng tôi sẽ khóa tùy chọn 3 ở đó, "một cái gì đó hoàn toàn khác". Đó chỉ là những gì tôi đã quen khi lần đầu tiên lập trình trong Basic (vâng, cách đây rất lâu). Lười biếng là lý do để tiếp tục sử dụng, 'nếu nó không bị hỏng, đừng sửa nó'.
Andrew Thompson

1
@MirroredFate Bạn có phải là hoàng tử cơ hội của người hâm mộ Ba Tư không? Tôi rất xin lỗi để đặt nó ở đây. Tôi không thể cưỡng lại
Anarach

11
@MirroredFate Đây là lý do tại sao tôi sử dụng iithay vì i. Khi tôi tham gia vào các cuộc thi lập trình, tôi thường phải tìm kiếm chỉ số vòng lặp để nói, +1hoặc -1từ đó để sửa lỗi do một lỗi. Trong những trường hợp đó, tìm kiếm iidễ dàng hơn nhiều so với tìm kiếm i, bất kể tôi đã sử dụng trình soạn thảo nào. Tương tự, tôi sử dụng jjkkcho các chỉ mục vòng lặp lồng nhau. :)
musically_ut

5

Tôi hoàn toàn đồng ý rằng đó setLocationByPlatform(true)là cách tốt nhất để chỉ định vị trí của JFrame mới nhưng trên thiết lập màn hình kép, bạn có thể gặp sự cố. Trong trường hợp của tôi, JFrame con được sinh ra trên màn hình 'của người khác'. Ví dụ: Tôi có GUI chính của mình trên Màn hình 2, tôi bắt đầu một JFrame mới setLocationByPlatform(true)và nó mở ra trên Màn hình 1. Vì vậy, đây là một giải pháp hoàn chỉnh hơn, tôi nghĩ:

...
// 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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.