簡體   English   中英

JFrame的大小如何實際起作用?

[英]How does the sizing of a JFrame actually work?

對於我正在做的事情,我沒有任何目的,只是用Java Swing來解決問題。 我現在擁有的是這三個變量:

    int[] gridIterations = {10,10}; //how many JButtons are made each row/column
    int[] frameSize = {600,600}; //size of the JFrame
    int[] gridSize = {60,60}; //by gridSize, I mean size of the JButtons

我還有一個嵌套的for循環,它使用這些變量來創建一個JButtons網格。 希望網格完全適合JFrame,但這是結果:

網格在JFrame的底部和右邊切斷

經過一些測試,我意識到框架實際上只適合所有的JButton,如果尺寸是(615, 631)但是我想知道,為什么它只適合這些參數,為什么,在所有數字中,它會是那些? 根據我的理解,60 * 10的簡單計算應該等於600並且成功地將所有按鈕都放入JFrame中,但我很可能忽略了某些東西。 那可能是什么? 謝謝。

JFrame的大小包括其insets。 這基本上意味着標題欄和邊框。

GridLayout將為您完美地完成這項工作,而且工作量更少。

網格布局

class GridButtons implements Runnable {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new GridButtons(4, 5));
    }

    final int rows;
    final int cols;

    GridButtons(int rows, int cols) {
        this.rows = rows;
        this.cols = cols;
    }

    @Override
    public void run() {
        JFrame frame = new JFrame();
        JPanel grid = new JPanel(new GridLayout(rows, cols));

        for (int i = 0; i < (rows * cols); ++i) {
            grid.add(new JButton() {
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(60, 60);
                }
            });
        }

        frame.setContentPane(grid);
        frame.pack();
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

很多內容歸結為內容和布局管理器的要求。 而不是看你想要框架的“有多大”,而是關注內容所需的空間量。 然后框架將“打包”在此周圍。

這意味着框架將“內容大小+框架邊框大小”大。

JFrame#pack考慮了內容的首選大小,並自動添加框架邊框插入。

因此,您需要的唯一事情是在完成向其添加內容之后調用JFrame#pack

所以,根據你的代碼:

public class Testing {

        public static void main(String[] args) {
                JFrame frame = new JFrame("hi");

                for (int i = 0; i < 10; i++) {
                        JButton a = new JButton();
                        a.setSize(20,20);
                        a.setLocation(20*i, 0);
                        frame.getContentPane().add(a);

                }
                frame.setLayout(null);
                frame.pack();
                frame.setVisible(true);
        }

}

您正在使用null布局。 JFrame#pack將使用布局管理器提供的信息來確定整個內容的“首選”大小。

避免使用null布局,像素完美布局是現代ui設計中的錯覺。 影響組件個體大小的因素太多,您無法控制。 Swing旨在與布局管理器一起工作,放棄這些將導致問題和問題的結束,您將花費越來越多的時間來糾正。

相反,專注於絕對的,可以在OS(甚至是具有相同OS的不同PC)之間變化,專注於用戶體驗。

正如已經證明的那樣,您可以使用GridLayout輕松實現此功能

網格布局

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridLayout(10, 10, 0, 0));
            for (int index = 0; index < 10 * 10; index++) {
                JButton btn = new JButton(String.valueOf(index)) {
                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(50, 50);
                    }
                };
                add(btn);
            }
        }

    }

}

如果,您需要更復雜的管理(即廣度深度),您可以使用GridBagLayout

看看在容器布置組件如何使用GridLayout以及如何使用GridBagLayout獲取更多詳細信息;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM