И есть также несколько других опций:
- Если вы хотите просто сделать невидимыми некоторые компоненты, вы можете добавить их в
CardLayout
с панелью, содержащей все из них, и пустой. - Если вы хотите применить действие к
Container
(например, JComponent
) и ко всем его дочерним элементам Component
s, то вы можете сделать рекурсивную процедуру для этого (ну, на самом деле это не обязательно, чтобы быть рекурсивным, но это, на мой взгляд, будет иметь более очевидный код).
код для первого варианта:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class Grouping1 {
public static void main(final String[] args) {
final JPanel buttons = new JPanel();
for (int i = 0; i < 3; ++i)
buttons.add(new JButton("Does nothing " + i));
final JPanel internal = new JPanel(new BorderLayout());
internal.add(new JTextArea("1234567890.\n0987654321."), BorderLayout.CENTER);
internal.add(buttons, BorderLayout.LINE_END);
final CardLayout clm = new CardLayout();
final JPanel clp = new JPanel(clm);
final JCheckBox enable = new JCheckBox("Click me", true);
enable.addActionListener(e -> clm.show(clp, enable.isSelected()? "FILLED": "BLANK"));
clp.add(internal, "FILLED");
clp.add(new JPanel(), "BLANK");
clm.show(clp, "FILLED");
final JPanel contents = new JPanel(new BorderLayout());
contents.add(clp, BorderLayout.CENTER);
contents.add(enable, BorderLayout.PAGE_START);
final JFrame frame = new JFrame("Components");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(contents);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
И код для второго варианта:
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.util.function.Consumer;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
public class Grouping2 {
public static void applyRecursively(final Container container,
final Consumer<Component> consumer) {
for (final Component child: container.getComponents())
if (child instanceof Container)
applyRecursively((Container) child, consumer);
else
consumer.accept(child);
consumer.accept(container);
}
public static void main(final String[] args) {
final JPanel buttons = new JPanel();
for (int i = 0; i < 3; ++i)
buttons.add(new JButton("Does nothing " + i));
final JPanel internal = new JPanel(new BorderLayout());
internal.add(new JTextArea("1234567890.\n0987654321."), BorderLayout.CENTER);
internal.add(buttons, BorderLayout.LINE_END);
final JCheckBox enable = new JCheckBox("Click me", true);
enable.addActionListener(e -> applyRecursively(internal, c -> c.setEnabled(enable.isSelected())));
final JPanel contents = new JPanel(new BorderLayout());
contents.add(internal, BorderLayout.CENTER);
contents.add(enable, BorderLayout.PAGE_START);
final JFrame frame = new JFrame("Components");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(contents);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
В обоих кодах просто установите флажок « Click me », чтобы переключить состояние компонентов.
Самый точный ответ хотя, по моему мнению, это может быть Джейсон, который позволяет группировать компоненты, которые вы можете выбрать. Наличие собственных Collection
из Component
s позволяет применять к ним действия без необходимости находиться в той же области GUI (как в моем первом коде) и без необходимости применять ко всем Container
детям действие (как в моем втором коде). Я думаю, это зависит от ваших потребностей.