Программисты JAVA общаются здесь
Anonymous
Скрытый компонент все еще занимает место
Сообщение
Anonymous » 19 янв 2026, 09:37
Я хочу динамически скрыть поле и переместить нижние компоненты вверх. По причине, которую я не могу понять, мне приходится обернуть поле в контейнер — в противном случае пространство останется пустым (если я вручную не вызову revalidate()).
Есть ли способ добиться желаемого поведения без избыточного вложения компонентов или повторной проверки вручную?
Кроме того, почему поведение в этих двух случаях различается?
Завернуто:
Не упаковано:
MRE:
Код: Выделить всё
import javax.swing.AbstractButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import java.awt.Component;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
public class GridBagLayoutDemo {
static JPanel fieldPanel;
static JTextField field;
public static void main(String[] args) {
Container mainPanel = createMainPanel();
JFrame frame = new JFrame("GridBagLayout Demo");
frame.setContentPane(mainPanel);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static Container createMainPanel() {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridy = 0;
constraints.gridx = 0;
constraints.anchor = GridBagConstraints.NORTHWEST;
constraints.weightx = 1;
constraints.fill = GridBagConstraints.BOTH;
panel.add(createToggle(), constraints);
constraints.gridy = 1;
panel.add(createFieldPanel(), constraints);
constraints.gridy = 2;
constraints.weighty = 1;
panel.add(createSomethingElse(), constraints);
return new JScrollPane(panel);
}
private static AbstractButton createToggle() {
JCheckBox toggle = new JCheckBox();
toggle.setText("Hide");
toggle.addActionListener(e -> fieldPanel.setVisible(!toggle.isSelected())); // vacated space occupied by "something else"
// toggle.addActionListener(e -> field.setVisible(!toggle.isSelected())); // vacated space stays blank
return toggle;
}
private static JPanel createFieldPanel() {
fieldPanel = new JPanel();
fieldPanel.add(createField());
return fieldPanel;
}
private static JTextField createField() {
field = new JTextField();
field.setColumns(10);
return field;
}
private static Component createSomethingElse() {
return new JLabel("Something else");
}
}
Java 8. Windows 10.
Подробнее здесь:
https://stackoverflow.com/questions/798 ... pies-space
1768804655
Anonymous
Я хочу динамически скрыть поле и переместить нижние компоненты вверх. По причине, которую я не могу понять, мне приходится обернуть поле в контейнер — в противном случае пространство останется пустым (если я вручную не вызову revalidate()). Есть ли способ добиться желаемого поведения без избыточного вложения компонентов или повторной проверки вручную? Кроме того, почему поведение в этих двух случаях различается? Завернуто: [img]https://i.sstatic.net/oT0bhSvA.png[/img] Не упаковано: [img]https://i.sstatic.net/kElWKHPb.png[/img] MRE: [code]import javax.swing.AbstractButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.WindowConstants; import java.awt.Component; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; public class GridBagLayoutDemo { static JPanel fieldPanel; static JTextField field; public static void main(String[] args) { Container mainPanel = createMainPanel(); JFrame frame = new JFrame("GridBagLayout Demo"); frame.setContentPane(mainPanel); frame.setLocationRelativeTo(null); frame.pack(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setVisible(true); } private static Container createMainPanel() { JPanel panel = new JPanel(new GridBagLayout()); GridBagConstraints constraints = new GridBagConstraints(); constraints.gridy = 0; constraints.gridx = 0; constraints.anchor = GridBagConstraints.NORTHWEST; constraints.weightx = 1; constraints.fill = GridBagConstraints.BOTH; panel.add(createToggle(), constraints); constraints.gridy = 1; panel.add(createFieldPanel(), constraints); constraints.gridy = 2; constraints.weighty = 1; panel.add(createSomethingElse(), constraints); return new JScrollPane(panel); } private static AbstractButton createToggle() { JCheckBox toggle = new JCheckBox(); toggle.setText("Hide"); toggle.addActionListener(e -> fieldPanel.setVisible(!toggle.isSelected())); // vacated space occupied by "something else" // toggle.addActionListener(e -> field.setVisible(!toggle.isSelected())); // vacated space stays blank return toggle; } private static JPanel createFieldPanel() { fieldPanel = new JPanel(); fieldPanel.add(createField()); return fieldPanel; } private static JTextField createField() { field = new JTextField(); field.setColumns(10); return field; } private static Component createSomethingElse() { return new JLabel("Something else"); } } [/code] Java 8. Windows 10. Подробнее здесь: [url]https://stackoverflow.com/questions/79868508/hidden-component-still-occupies-space[/url]