为什么在JFrame上设置setPreferredSize()很糟糕? [英] Why setting setPreferredSize() on JFrame is bad?

查看:355
本文介绍了为什么在JFrame上设置setPreferredSize()很糟糕?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 setPreferredSize()设置 JFrame 的首选大小?认为不好?

Is setting preferred size of JFrame using setPreferredSize() considered bad?

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

If it is bad, what is good way to change JFrame window size to dimension I need.

我知道如何设置组件以反映我需要的最终JFrame维度。但是,如果我在调用 pack()之前使用调用 setPreferredSize()来更改首选大小以更改最终 JFrame 大小不好?如果是这样的原因?

I know laying components in way to reflect final JFrame dimension that I need. But if I use shortcut to change preferred size using call setPreferredSize() just before call to pack() to change final JFrame size is bad? If so why?

例如我有样本表格:

显示时不显示首选尺寸。

This is displayed without setting preferred size.

现在我可以调用 setPreferredSize()来调整表单大小,然后再调用 pack()

Now I can resize form with call to setPreferredSize() before call to pack().

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

在设置组件尺寸时,我可以产生类似的效果。但是只需调用 setPreferredSize()设置帧大小有什么不利。

I can have similar effect with setting components size while laying it out. But what is disadvantage of setting frame size with just call to setPreferredSize().

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

I can think setting preferred size as resizing displayed window manually with mouse after it has been displayed. Isn't it?

代码:

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


推荐答案

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

The main reason it would be considered bad (bad is probably too strong a word, unwise might be better) is the use of unknown (magic) numbers, rather than empirical values.

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

Every platform (and even similar OS running on different hardware and settings) has it's own means for rendering content which can change the amount of space that individual components require.

关于文本字段和文本区域等内容,您可以提供有关可用于更改a的列数(以及文本区域的行)的建议框架最终尺寸,使用 setColumns setRows 例如......

In regards to things like text fields and text-areas, you can make suggestions about the number of columns (and rows for text areas) which can be used to change a frames final size, using setColumns and setRows for example...

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

So, using the following code...

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

哪个产生......

Which produces...

现在只更改一行......

Now by changing only one line...

private JTextArea addressTextArea = new JTextArea(10, 20);
                                // Only this value ---^

它产生了这个...

再次......

private JTextArea addressTextArea = new JTextArea(10, 40);
                                // Only this value ---^

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

I could change the number of rows for the JTextArea and effect the height of the window as well.

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

The difference is, these values are used in combination with the systems font metrics to calculate the preferred size of the components when the program is run, so it will be different for different systems and platforms...

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

The main point to layouts is to spend your time focused on the intent and the work flow and not trying to get a pixel perfect solution, because there's simply no such thing...talk to web developers, they have the same issues, just much worse (multiple browsers on a single system, all rendering differently)

这篇关于为什么在JFrame上设置setPreferredSize()很糟糕?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆