Java 为什么在JFrame上设置setPreferredSize()不好?
使用Java 为什么在JFrame上设置setPreferredSize()不好?,java,swing,Java,Swing,使用setPreferredSize()设置JFrame的首选大小是否被认为是错误的 如果是坏的,什么是将JFrame窗口大小更改为我需要的尺寸的好方法 我知道如何放置组件以反映我需要的最终JFrame尺寸。但如果在调用pack()更改finalJFrame大小之前,使用快捷方式更改首选大小,那么大小是否不好?如果是,为什么 例如,我有一个示例表单: 显示时不设置首选大小 现在,在调用pack()之前,我可以通过调用setPreferredSize()调整表单大小 这通过调用显示:setPr
setPreferredSize()
设置JFrame
的首选大小是否被认为是错误的
如果是坏的,什么是将JFrame
窗口大小更改为我需要的尺寸的好方法
我知道如何放置组件以反映我需要的最终JFrame尺寸。但如果在调用pack()
更改finalJFrame
大小之前,使用快捷方式更改首选大小,那么大小是否不好?如果是,为什么
例如,我有一个示例表单:
显示时不设置首选大小
现在,在调用pack()
之前,我可以通过调用setPreferredSize()
调整表单大小
这通过调用显示:setPreferredSize(新维度(500300))代码>
我可以有类似的效果,设置组件的大小,而布局。但是,只调用setPreferredSize()
设置帧大小有什么缺点呢
我可以认为设置首选大小是在显示窗口后用鼠标手动调整其大小。不是吗
代码:
就个人而言,我认为使用frame.setPreferredSize()
调整JFrame
窗口的大小没有什么错。事实上,我认为这是调整其大小的最合适的解决方案
但现在正是区分一些最常见的调整大小方法的好时机:
frame.pack()
,如前所述,基本上为每个单独的元素采用首选的大小
frame.setSize()
按预期调整窗口大小,但仅当组件的父级没有明确定义布局管理器时。
对这种方法的使用进行了讨论
这并没有留下任何其他方法来定义窗口的大小,这就是为什么我认为设置首选窗口大小是最好的方法。我仍然会确保定义setMinimumSize()
和setMaximumSize()
,以确保在所有情况下正确调整组件的大小
编辑:
这篇文章中的其他帖子让我想到了在设置组件时使用“魔法常量”。例如,在web开发中,通常不赞成使用像素,因为系统会发生很大变化。我想看看这是否也适用于维度。简言之,我的研究结果得出结论,事实并非如此
这是一个JFrame,其首选尺寸为新尺寸(200300)
在我的MacBook Pro上,带有视网膜显示器:
新尺寸(200300)的首选尺寸
这是一个JFrame,在我的华硕Windows平板电脑(非视网膜显示器)上拍摄的首选尺寸为新尺寸(200300)
:
新尺寸(200300)的首选尺寸
这些窗口看起来一模一样,尽管我找不到发布的,但尺寸实际上已经成比例了,考虑到显示器的高度、宽度和分辨率,可以在所有设备上生成近乎精确的渲染。我想你会说,这是有道理的,因为这是Java的方式
话虽如此,我认为有一些事情需要注意:
正如所指出的,UIManager LookAndFeel
跨平台之间的差异
老实说,我认为最后的决定是留给程序员的。在这次测试之后,我仍然得出结论,如果您不打算实现半复杂的窗口管理器,那么使用frame.setPreferredSize()
是最好的选择之一。即使如此,我认为总会有一些未知的变化。被认为是不好的主要原因(坏可能是一个太强的词,不明智可能更好)是使用未知(神奇)数字,而不是经验值
每个平台(甚至是运行在不同硬件和设置上的类似操作系统)都有自己的内容呈现方式,可以改变各个组件所需的空间量
对于诸如文本字段和文本区域之类的内容,您可以使用setColumns
和setRows
对可用于更改帧最终大小的列数(以及文本区域的行数)提出建议
所以,使用下面的代码
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);
}
}
}
这就产生了
现在只改变一行
private JTextArea addressTextArea = new JTextArea(10, 20);
// Only this value ---^
它产生了这个
再一次
private JTextArea addressTextArea = new JTextArea(10, 40);
// Only this value ---^
我可以更改JTextArea
的行数,也可以影响窗口的高度
不同之处在于,这些值与系统字体度量结合使用,以计算程序运行时组件的首选大小,因此,对于不同的系统和平台,这些值会有所不同
布局的要点是将时间集中在意图和工作流程上,而不是试图获得像素完美的解决方案,因为根本没有这样的事情……与web开发人员交谈,他们有相同的问题,只是更糟糕(单个系统上有多个浏览器,所有渲染方式都不同)被认为不好的主要原因是使用未知(神奇)数字,而不是经验值。每个平台(甚至是运行在不同硬件和设置上的类似操作系统)都有自己的内容呈现方式,可以改变各个组件所需的空间量。对于像文本字段和文本区域这样的东西,你可以就可以用来更改帧最终大小的列数(以及文本区域的行数)提出建议。我有一个开发人员做过这种事情,当用户使用比他设计的分辨率小的分辨率时,这种事情会在我们面前爆发(另一个问题是滤网包装过多,并且
private JTextArea addressTextArea = new JTextArea(10, 40);
// Only this value ---^