为什么在JFrame上设置setPreferredSize()很糟糕?

nul*_*ptr 4 java swing

是设置的最佳尺寸JFrame采用setPreferredSize()认为是坏?

如果不好,有什么方法可以将JFrame窗口大小更改为我需要的尺寸.

我知道按照我需要的最终JFrame维度来铺设组件.但是,如果我使用快捷方式在调用setPreferredSize()之前使用调用更改首选大小pack()更改最终JFrame大小是不是很糟糕?如果是这样的话?

例如,我有样本表格:

在此输入图像描述

显示时不设置首选大小.

现在我可以在调用setPreferredSize()之前通过调用调整表单大小pack().

在此输入图像描述

通过调用显示: setPreferredSize(new Dimension(500, 300));

在铺设时,我可以设置组件尺寸具有类似的效果.但是只需调用就可以设置帧大小的缺点setPreferredSize().

我可以考虑将首选大小设置为在显示后用鼠标手动调整显示窗口的大小.不是吗?

码:

import java.awt.Dimension;

import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class MyFrame extends JFrame {
    private static final long serialVersionUID = 1L;

    private JTextField fullNameTextField = new JTextField();
    private JTextField emailIDTextField = new JTextField();
    private JTextArea addressTextArea = new JTextArea();
    private JButton submitButton = new JButton("Submit");
    private JButton cancelButton = new JButton("Cancel");

    public MyFrame(){
        super("MyFrame");

        layoutComponents();

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationByPlatform(true);

        setPreferredSize(new Dimension(500, 300));

        pack();
    }

    private void layoutComponents(){
        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);

        JLabel fullNameLabel = new JLabel("Full Name:");
        JLabel emailIDLabel = new JLabel("Email ID:");
        JLabel addressLabel = new JLabel("Address:");

        JScrollPane addressScrollPane = new JScrollPane(addressTextArea);

        layout.setHorizontalGroup(
                layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                        .addGap(10)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                                .addGroup(layout.createSequentialGroup()
                                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                                                .addComponent(fullNameLabel)
                                                .addComponent(emailIDLabel)
                                                .addComponent(addressLabel)
                                            )
                                        .addGap(15)
                                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                                                .addComponent(fullNameTextField, 10, 200, Short.MAX_VALUE)
                                                .addComponent(emailIDTextField)
                                                .addComponent(addressScrollPane)
                                                .addGroup(layout.createSequentialGroup()
                                                        .addGap(0, 0, Short.MAX_VALUE)
                                                        .addComponent(submitButton)
                                                        .addGap(10)
                                                        .addComponent(cancelButton)
                                                    )
                                            )
                                    )
                            )
                        .addGap(10)
                    )
            );

        layout.setVerticalGroup(
                layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                        .addGap(10)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(fullNameLabel)
                                .addComponent(fullNameTextField)
                            )
                        .addGap(5)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(emailIDLabel)
                                .addComponent(emailIDTextField)
                            )
                        .addGap(5)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(addressLabel)
                                .addComponent(addressScrollPane, 20, 60, Short.MAX_VALUE)
                            )
                        .addGap(15)
                        .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                .addComponent(submitButton)
                                .addComponent(cancelButton)
                            )
                        .addGap(10)
                    )
            );

        layout.linkSize(submitButton, cancelButton);

        getRootPane().setDefaultButton(submitButton);
    }

    public static void main(String [] args){
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new MyFrame().setVisible(true);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

Mad*_*mer 6

它被认为是坏的主要原因(坏的可能是一个词太强,不明智可能更好)是使用未知(魔法)数字,而不是经验值.

每个平台(甚至是在不同硬件和设置上运行的类似操作系统)都有自己的渲染内容的方法,可以改变单个组件所需的空间量.

在问候之类的文本字段和文本区域,您可以对列数的建议(和文本区行),它可以用来改变一个帧的最终尺寸,使用setColumnssetRows例如...

所以,使用以下代码......

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestLayout101 {

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

    public TestLayout101() {
        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 {

        private JTextField fullNameTextField = new JTextField(10);
        private JTextField emailIDTextField = new JTextField(10);
        private JTextArea addressTextArea = new JTextArea(10, 20);
        private JButton submitButton = new JButton("Submit");
        private JButton cancelButton = new JButton("Cancel");

        public TestPane() {

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.WEST;
            gbc.insets = new Insets(4, 4, 4, 4);

            add(new JLabel("Full Name: "), gbc);
            gbc.gridy++;
            add(new JLabel("Email ID: "), gbc);
            gbc.gridy++;
            gbc.anchor = GridBagConstraints.NORTHWEST;
            add(new JLabel("Address: "), gbc);

            gbc.gridx++;
            gbc.gridy = 0;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weightx = 1;

            add(fullNameTextField, gbc);
            gbc.gridy++;
            add(emailIDTextField, gbc);
            gbc.gridy++;
            gbc.weighty = 1;
            add(new JScrollPane(addressTextArea), gbc);

            JPanel buttons = new JPanel(new FlowLayout(FlowLayout.RIGHT, 4, 4));
            buttons.add(submitButton);
            buttons.add(cancelButton);

            gbc.gridx = 0;
            gbc.gridy++;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weighty = 0;
            add(buttons, gbc);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

哪个产...

紧凑

现在只改变一行......

private JTextArea addressTextArea = new JTextArea(10, 20);
                                // Only this value ---^
Run Code Online (Sandbox Code Playgroud)

它产生了......

微型

然后再次...

private JTextArea addressTextArea = new JTextArea(10, 40);
                                // Only this value ---^
Run Code Online (Sandbox Code Playgroud)

豪华

我也可以更改JTextArea窗口的行数并影响窗口的高度.

不同的是,这些值与系统字体度量结合使用,以计算程序运行时组件的首选大小,因此对于不同的系统和平台,它们将有所不同......

布局的要点是花时间专注于意图和工作流程而不是试图获得像素完美的解决方案,因为根本没有这样的事情......与Web开发人员交谈,他们有同样的问题,只是很多更糟糕的是(单个系统上的多个浏览器,所有渲染都不同)