レイアウト要件の場合と同様に、タスクは適切な LayoutManager を見つけて、コンポーネントの可視性に応じて利用可能なスペースをどのように配分するかを判断することです。これで、あなたの仕事は要約すると、可視性を切り替えて身を乗り出すことになります。
ほとんどのコア マネージャは、非表示のコンポーネントを単純に無視します (これは、必要な場合とそうでない場合があります)。高度なマネージャーは、可視コンポーネントとまったく同じ方法で処理することから、無視することまで、あらゆる範囲で構成できます。Fi MigLayout (現時点での私のお気に入り) には、4 つのレベルの非表示モードがあります (同じように、コンポーネントのサイズを 0,0 に、コンポーネントのサイズを 0,0 に変更し、周囲のすべてのギャップをゼロにし、完全に無視します)。
以下は簡単な例です。異なる動作を確認するには、textField と一緒に textfield のラベルを非表示にして、hidemode のさまざまな順列を試してみてください。
// hidemode 3 == ignore in layout
// hidemode 2 == zero size and zero gaps
// hidemode 1 == zero size
// hidemode 0 == same as visible
MigLayout layout = new MigLayout("wrap 2, hidemode 3");
JComponent content = new JPanel(layout);
JPopupMenu popup = new JPopupMenu();
for (int i = 0; i < 5; i++) {
JTextField field = new JTextField("field " + i, 20);
field.setName(field.getText());
JLabel label = new JLabel("Label " + i);
label.setLabelFor(field);
content.add(label);
content.add(field);
popup.add(new JCheckBoxMenuItem(new ToggleVisibilityAction(field, true)));
}
content.setComponentPopupMenu(popup);
// action to toggle the visibility of a target component
// optionally w/out its label
public static class ToggleVisibilityAction extends AbstractAction {
private JComponent target;
private boolean hideLabel;
public ToggleVisibilityAction(JComponent comp, boolean hideLabel) {
super(comp.getName());
this.target = comp;
this.hideLabel = hideLabel;
putValue(SELECTED_KEY, target.isVisible());
}
@Override
public void actionPerformed(ActionEvent e) {
boolean visible = (boolean) getValue(SELECTED_KEY);
target.setVisible(visible);
if (hideLabel && target.getClientProperty("labeledBy") instanceof JComponent) {
((Component) target.getClientProperty("labeledBy")).setVisible(visible);
}
target.getParent().revalidate();
}
}