正確なコンテキストについてはまだ完全にはわかりませんが、「答え」から判断すると、コンポーネントの制約をその場で変更しているようです。影響を受けるパーツの再レイアウトをトリガーするには、次のことを行う必要があります。
- 制約が変更された子/renを無効にします(注:親を無効にするだけでは不十分です)。これにより、必要に応じて階層がバブルアップします。
- 階層の上位にある適切なコンテナを検証します
スニペット:
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);
}
編集
この答えのどの部分が間違っていると正確に言っているのかわからない-明らかに私はそれについての詳細な知識なしではあなたの問題を解決することができなかった;-)
不思議なことに、階層の上位にある再検証が、有効な孫/子の再レイアウトにどのようにつながるのか疑問に思っています。validate/Treeは明らかに有効なコンポーネントで停止します。以下は、遊ぶためのコードスニペットです
- これは2レベルの階層であり、2つの子を持つ親です。
- アクションは、足元の姉妹のレイアウトに影響するプロパティを変更し(レイアウトのv / hgapを変更します)、親を再検証します
結果は、親のLayoutManagerに応じてfiによって異なります
- 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);