仍然不完全确定您的确切上下文,但从您的“答案”来看,您似乎正在动态更改组件约束。要触发受影响部分的重新布局,您需要
- 使约束已更改的子/人无效(注意:使父无效是不够的),这将根据需要使层次结构冒泡
- 验证层次结构中的适当容器
片段:
ExpandableGridBagLayout bag = panel2.getLayout();
bag.setExpand(true);
for(Component child: panel2.getComponents())
child.invalidate();
panel1.validate();
没有公共 api 可以递归地使给定容器下的所有内容无效(invalidateTree 是包私有的)。一个快速的技巧是临时切换父容器的字体(内部消息 invalidateTree)
/**
* Invalidates the component hierarchy below the given container.<p>
*
* This implementation hacks around package private scope of invalidateTree by
* exploiting the implementation detail that the method is internally
* used by setFont, so we temporary change the font of the given container to trigger
* its internal call.<p>
*
* @param parent
*/
protected void invalidateTree(Container parent) {
Font font = parent.getFont();
parent.setFont(null);
parent.setFont(font);
}
编辑
不知道这个答案的哪一部分是不正确的——显然,如果没有任何详细的知识,我就无法解决你的问题;-)
好奇的我想知道层次结构中的重新验证如何导致有效大/子的重新布局:验证/树显然停在一个有效的组件上。下面是一个代码片段
- 这是一个两级层次结构,一个有两个孩子的父母
- 该动作改变了它脚下姐妹的布局影响属性(我们改变了布局的 v/hgap)并重新验证了父级
结果会有所不同,具体取决于父级的 LayoutManager
- 使用 FlowLayout 什么都不会发生,
- 使用 BoxLayout 它可能会被验证,具体取决于
看起来一个有效孩子的重新布局可能是(或不是)更高层重新布局的副作用 - 没有任何保证会发生并且难以预测。我不想依赖任何东西;-)
final JComponent sister = new JPanel();
final Border subBorder = BorderFactory.createLineBorder(Color.RED);
sister.setBorder(subBorder);
sister.add(new JTextField(20));
sister.add(new JButton("dummy - do nothing"));
JComponent brother = new JPanel();
brother.setBorder(BorderFactory.createLineBorder(Color.GREEN));
brother.add(new JTextField(20));
// vary the parent's LayoutManager
final JComponent parent = Box.createVerticalBox();
// final JComponent parent = Box.createHorizontalBox();
// final JComponent parent = new JPanel();
parent.add(sister);
parent.add(brother);
// action to simulate a change of child constraints
Action action = new AbstractAction("change sub constraints") {
@Override
public void actionPerformed(ActionEvent e) {
FlowLayout layout = (FlowLayout) sister.getLayout();
layout.setHgap(layout.getHgap() * 2);
// layout.setVgap(layout.getVgap() * 2);
// sister.invalidate();
parent.revalidate();
}
};
brother.add(new JButton(action));
JFrame frame = new JFrame("play with validation");
frame.add(parent);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);