在通过add
和remove
手动交换组件后,我在容器上调用validate()
。根据该文件,是用来引起容器容器在调用验证后不会自动调整大小
validate方法再次布置其 子组件。当容器的 子容器已被 显示后,应修改此容器的 子组件(添加到容器或从容器中移除,或者 已更改布局相关信息)。
短语“布局其子又”让我觉得,容器将相应调整自身的大小,但它没有。相反,在调用validate()
后,我还需要调用pack()
以查看其所有子组件。
这是为什么?难道我做错了什么?
在通过add
和remove
手动交换组件后,我在容器上调用validate()
。根据该文件,是用来引起容器容器在调用验证后不会自动调整大小
validate方法再次布置其 子组件。当容器的 子容器已被 显示后,应修改此容器的 子组件(添加到容器或从容器中移除,或者 已更改布局相关信息)。
短语“布局其子又”让我觉得,容器将相应调整自身的大小,但它没有。相反,在调用validate()
后,我还需要调用pack()
以查看其所有子组件。
这是为什么?难道我做错了什么?
(可能是由于这种模棱两可的描述latest javaDoc改变)
JavaDoc 7是不说,
验证方法用于使容器布置其子组件NTS 再次 ..
所以其只铺设的组件,而你又需要一个pack()
。
注意pack()明确表示,
此窗口的大小,以适合其子组件的首选大小和布局。
我认为你自己回答了你的问题,希望帮你这个演示
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class AddComponentsAtRuntime {
private JFrame f;
private JPanel panel;
private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack;
public AddComponentsAtRuntime() {
JButton b = new JButton();
b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(600, 10));
panel = new JPanel(new GridLayout(0, 1));
panel.add(b);
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(panel, "Center");
f.add(getCheckBoxPanel(), "South");
f.setLocation(200, 200);
f.pack();
f.setVisible(true);
}
private JPanel getCheckBoxPanel() {
checkValidate = new JCheckBox("validate");
checkValidate.setSelected(false);
checkReValidate = new JCheckBox("revalidate");
checkReValidate.setSelected(false);
checkRepaint = new JCheckBox("repaint");
checkRepaint.setSelected(false);
checkPack = new JCheckBox("pack");
checkPack.setSelected(false);
JButton addComp = new JButton("Add New One");
addComp.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JButton b = new JButton();
b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(600, 10));
panel.add(b);
makeChange();
System.out.println(" Components Count after Adds :" + panel.getComponentCount());
}
});
JButton removeComp = new JButton("Remove One");
removeComp.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int count = panel.getComponentCount();
if (count > 0) {
panel.remove(0);
}
makeChange();
System.out.println(" Components Count after Removes :" + panel.getComponentCount());
}
});
JPanel panel2 = new JPanel();
panel2.add(checkValidate);
panel2.add(checkReValidate);
panel2.add(checkRepaint);
panel2.add(checkPack);
panel2.add(addComp);
panel2.add(removeComp);
return panel2;
}
private void makeChange() {
if (checkValidate.isSelected()) {
panel.validate();
}
if (checkReValidate.isSelected()) {
panel.revalidate();
}
if (checkRepaint.isSelected()) {
panel.repaint();
}
if (checkPack.isSelected()) {
f.pack();
}
}
public static void main(String[] args) {
AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime();
}
}
+1:@mKorbel总是有很好的演示:) – COD3BOY 2012-01-05 14:37:56
好的演示,可能会保持它的方便! – davidfrancis 2012-01-05 15:04:39
的根本,而微妙的假设,在这里打球:布局和大小有直接的关系,1对1。 情况并非如此,并且是Swing编程中的一个常见假设。尺寸是布局和尺寸约束的结果。
布局是:
如果布局管理能适应你给它的成分,在不改变容器的整体尺寸,它不会改变容器的大小。另一方面,拨打pack是明确要求尽量减少正在使用的空间。这是你看到结果的根本原因。
有些事情你可以尝试:
这是棘手与Swing,因为你要明白在p包括管道,布局管理器以及窗口系统的一些细节。当谈到Swing文档(以及所有的方法和做任何事情的几种不同方式)时,我尝试用“不采取任何措施”的方式阅读文档,这意味着“这种方法的最小可能性是什么文件意味着它可能会这样做“,除非你观察到其他行为,否则不要被认为它不止于此。
最后,我想补充一点,在一般的布局管理的作业没有大小容器的这么多,因为它是把部件在一些关系到彼此,根据布局战略(这在additional detail here讨论) 。这个想法是,通过适当的LayoutManager,您可以指定一个基本布局策略,结果当您调整窗口大小时,LayoutManager将智能地移动组件,以便您的UI继续遵循整体策略。通过这种方式,布局基本上是独立于其工作空间的整体大小的,因此他们尽量不对可用空间做出假设 - 而是采取给定的大小并尝试做什么说得通。除非您明确地将尺寸限制放在组件上,否则不能保证它们的尺寸。
这意味着,如果LayoutManager不相信它需要调整大小以适应其整体策略,基本上它不会调整它的大小。另一方面,拨打pack是一个明确的要求,可以将所有东西放在一起并消除额外的空间。
使用Swing时,我使用'revalidate()'。同样,它不会调整框架大小,但会调整Container的大小,这可能会导致布局发生变化。例如,如果容器位于滚动窗格中,则可能会看到添加或删除滚动条。 – camickr 2012-01-05 16:20:05
@camickr - 可能会误解你的意思,但在容器上重新验证将永远不会调整容器的大小,只有它的子项 – kleopatra 2012-01-06 10:34:36
@kleopatra,再次看我的评论,我想我应该没有使用术语“容器”。我使用的术语“容器”是指“jpanel”,并试图强调它只会影响“容器”内组件的布局。它不会调整顶层容器(JFrame,JDialog,JWindow)。 – camickr 2012-01-06 16:13:16